home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
basic
/
qbscr15.zip
/
QBSCR.DOC
< prev
next >
Wrap
Text File
|
1989-09-05
|
213KB
|
5,509 lines
Q B S C R
S C R E E N R O U T I N E S
for the
QuickBASIC 4.0+ Programmer
V e r s i o n 1 . 5
Conceived and Created by
Tony Martin
of
The BAD SOFTWARE Company
1611 Harvest Green Ct.
Reston, VA 22094
September 1 1989
Software and Documentation (C) Copyright 1989 by
Tony Martin
T A B L E O F C O N T E N T S
-------------------------------------------------------------
Welcome to the QBSCR Screen Routines . . . . . . 1
A Few Notices . . . . . . . . . . . . . . . . . 2
Files Included with QBSCR . . . . . . . . . . . 3
A QBSCR Glossary . . . . . . . . . . . . . . . . 4
A Synopsis of the QBSCR Screen Routines . . . . 8
The SCREEN BUILDER Program . . . . . . . . . . . 12
The DEMO Program . . . . . . . . . . . . . . . . 13
The REF Program . . . . . . . . . . . . . . . . 14
The COLCONST.BAS file . . . . . . . . . . . . . 17
Incorporating the Screen Routines
into Your Own Programs . . . . . . . . . . 18
The QBSCR Routines Detailed Descriptions . . . . 22
Subprogram BANNER . . . . . . . . . . . . . . . 23
Function BLOCKSIZE . . . . . . . . . . . . . . . 25
Subprogram BLOCKRESTORE . . . . . . . . . . . . 26
Subprogram BLOCKSAVE . . . . . . . . . . . . . . 28
Subprogram BUILDSCREEN . . . . . . . . . . . . . 30
Subprogram CENTER . . . . . . . . . . . . . . . 32
Subprogram CLRSCR . . . . . . . . . . . . . . . 33
Function COLORCHK . . . . . . . . . . . . . . . 34
Function GETBACKGROUND . . . . . . . . . . . . . 35
Function GETFOREGROUND . . . . . . . . . . . . . 36
Subprogram GETSCREEN . . . . . . . . . . . . . . 37
Function GETSTRING . . . . . . . . . . . . . . . 38
Function GETVIDEOSEGMENT . . . . . . . . . . . . 40
page ii
T A B L E O F C O N T E N T S ( c o n ' d )
-------------------------------------------------------------
Function MAKEMENU . . . . . . . . . . . . . . . 42
Subprogram MAKEWINDOW . . . . . . . . . . . . . 48
Subprogram MULTIMENU . . . . . . . . . . . . . . 55
Subprogram OFFCENTER . . . . . . . . . . . . . . 64
Subprogram PUTSCREEN . . . . . . . . . . . . . . 65
Subprogram QBPRINT . . . . . . . . . . . . . . . 66
Function SCREENBLANK . . . . . . . . . . . . . . 68
Subprogram SCRNRESTORE . . . . . . . . . . . . . 70
Subprogram SCRNSAVE . . . . . . . . . . . . . . 72
Subprogram WIPE . . . . . . . . . . . . . . . . 74
Techniques for Using QBSCR . . . . . . . . . . . 76
Displaying and Popping a Window . . . . . . . . 77
Visual Effects with BUILDSCREEN and CLRSCR . . . 80
Window Making Techniques . . . . . . . . . . . . 81
Menu Techniques . . . . . . . . . . . . . . . . 82
Cross Reference - Routine Dependencies . . . . . 84
Closing Notes . . . . . . . . . . . . . . . . . 85
Registration Form . . . . . . . . . . . . . . . 86
page iii
Welcome to the QBSCR Screen Routines
-------------------------------------------------------------
The QBSCR Screen Routines is a collection of
utilities for the discriminating QuickBASIC
programmer. As the name implies, they are screen
and display oriented. With these routines and very
little effort, your own programs can be extremely
professional in appearance. They are quite easy to
use and incorporate into your own programs.
The Screen Routines are especially useful if you
are in a hurry. The QBSCR package can cut
development time of any project in half, since all
the display routines are already written for you.
Incorporate the QBSCR routines into your program
with a single line of code, and all of the QBSCR
resources are at your disposal.
The screen routines are more than just a toolbox,
however. They can also fill the role of tutor. By
reading through the source code of these routines,
you will quickly find yourself learning how to do
new things with QuickBASIC.
page 1
A Few Notices
-------------------------------------------------------------
The QBSCR Screen Routines are made available to you
through the concept of shareware. Shareware is
software that authors encourage others to
distribute among friends and colleagues. In this
way the author's software not only becomes widely
known, but consumers may "try before they buy."
Once they decide to keep and use the software, they
send in a registration fee, or payment for the
software, to the author.
The Screen Routines have a registration fee of
$15.00. If you decide to actually use the routines
in any of your programs, you should register them.
As it can be very easy to forget to register, or
simply ignore it, I provide you with an incentive.
To any who register the QBSCR Screen Routines (or
any other software products from BAD SOFTWARE), I
will send an official disk set containing the
latest version of the software, as well as a free
program. The free program is a graphics
entertainment program called LASER. This graphics
program is fun to use and watch, and can also be
a great stress management tool. To all registered
users of the QBSCR Screen Routines will go a copy
of LASER.
If you decide to register the Screen Routines, you
can send a check for $15.00 made out to Tony Martin
to the address at the end of this document. See
the registration form on the last page for details.
This last notice is posted here for legal reasons.
You've probably seen one in every software
package, but it's quite necessary. Bear with me.
The QBSCR Screen routines are (C) Copyright 1989 by
Tony Martin. I retain all rights to the source
code and documentation. I cannot be held
responsible for any consequences arising from the
ability or inability to use this software. You may
not charge money of any kind for this software
without prior written permission from myself. On
the other hand, I don't expect any credits or
royalties if you use these routines in your own
software.
Let's now move on to the fun parts.
page 2
Files Included with QBSCR
-------------------------------------------------------------
There are several files included with the QBSCR
Screen Routines. Below is a list of the files and
a brief description of what each is.
File... ...Description
---------------------------------------------------
QBSCR.BAS The source code for the routines
themselves.
QBSCR.DOC The documentation file you are
reading now.
QBSCR.INC An Include file that contains all the
necessary DECLARE statements for the
QBSCR routines.
COLCONST.BAS A short file of code to include in
your programs that use colors.
Assigns color values to named
constants.
DEMO.BAS Source code for a sample program that
illustrates how to use all of the
QBSCR routines.
DEMO.EXE The DEMO program compiled, linked,
and ready to run.
SB.EXE The new Screen Builder program, used
to create premade screen displays.
*.CLR Color versions of premade screen
displays, mostly for the DEMO
program.
*.MON Monochrome versions of premade screen
displays, mostly for the DEMO
program.
REF.BAS An example of a real-life application
program that makes good use of the
Screen Routines.
REF.EXE The REF program compiled, linked, and
ready to run.
WHATS.NEW Describes the revision history of the
QBSCR Screen Routines.
page 3
A QBSCR Glossary
-------------------------------------------------------------
There are a few terms used in this documentation
particular to the QBSCR Screen Routines and the
functions employed within the package. This
section is a short glossary that will hopefully
clarify the meanings of these terms with respect to
this software.
ASCII (characters)
---------------------------------------------------
ASCII is an acronym for American Standard Code
for Information Interchange. It refers to the
standard character set found on computers that
support it. IBM PCs and compatibles are ASCII
machines. The characters are referenced by
number and are limited to 256 possible
characters (0 - 255). The standard only
applies to characters 0 through 127. The
characters 128 through 255 are left open to
the machine builder. IBM chose to create a
set of box drawing characters as part of the
extended characters, and we use them to create
window frames.
Burn-in
---------------------------------------------------
When an image is left on a display screen for
a long period of time, the screen can retain a
permanent ghost of this image. The phosphor
inside your monitor that glows to produce
characters on your screen will have this image
more or less permanently etched into it. This
is called screen Burn-in. It usually requires
the same image to be displayed eight hours a
day over a period of several months. It is
best avoided.
DECLARE Statement
---------------------------------------------------
A DECLARE statement is a standard QuickBASIC
statement. It is not executable, meaning it
tells the compiler something when the program
is compiled, and really does nothing at
runtime. The DECLARE statement is used to
tell the compiler information about
subprograms and functions before it gets to
them. Using the DECLARE statement allows you
page 4
to utilize your subprograms and functions
without the use of the CALL statement. If you
had a subprogram called Clock which displayed
the time in the upper left corner of your
screen, you would have to issue the following
statement in your program:
CALL Clock
You could create a DECLARE statement for it
and place it at the beginning of your program.
It would look like this:
DECLARE SUB Clock ()
It would allow you to use your Clock routine
by simply issuing the statement
Clock
in your program.
Display Memory
---------------------------------------------------
Display memory is the physical memory inside
your computer, specifically on your graphics
card, that stores the contents of the
display. By knowing where this memory begins
in terms of memory addresses, you can peek
there and see what's on the screen. The
SCRNSAVE and SCRNRESTORE routines rely
entirely on the contents of this memory to
save and restore information from and to the
screen.
Explode
---------------------------------------------------
Explode, when used in the context of screen
windows, is a display effect. If a window
explodes onto the screen, it appears to
rapidly expand outward from nothing to its
full size.
Frame
---------------------------------------------------
A frame is simply a border around a window.
It is drawn with standard IBM extended ASCII
graphics characters.
page 5
Highlight(ed)
---------------------------------------------------
Highlight(ed) refers to a character or set of
characters that stand out from others on the
screen. This is generally done by making them
brighter or a different color. Highlighting
is used to call attention to certain
character(s), indicating that they are
especially significant. In the QBSCR
routines, the "Quick Access" keys are
highlighted so they are easily recognized.
Menu
---------------------------------------------------
A menu is a list of 2 or more choices, or
entries, from which a single entry is chosen
by a user. The method of selection varies
from program to program. In the QBSCR Screen
Routines, selection is made either by use of a
selection bar or "Quick Access" keys.
"Quick Access" Key
---------------------------------------------------
A "Quick Access" key is a key you can hit
within a menu to give you direct access to any
given entry. Each menu entry (or choice) will
have associated with it a unique key that will
provide this direct access. The key must be
one of the letters that make up the text of
the entry. The "Quick Access" key for each
entry will be highlighted to indicate which
letter is the "Quick Access" key.
Quick Library
---------------------------------------------------
A Quick Library is a collection of routines in
a special format, like the QBSCR Screen
Routines, that can be used to run programs
from inside the QuickBASIC environment. It
has a .QLB extension. Refer to your
QuickBASIC documentation for information on
how to create them.
Parameter
---------------------------------------------------
A parameter is a piece of information that is
passed to a subprogram or a function. For
example, the QBSCR routine CENTER, which
centers text on any given row of the screen,
must know two pieces of information: the
string of text you want centered, and the row
of the screen on which to center it. Thus, the
CENTER routine requires two parameters.
page 6
Premade Display (or screen)
---------------------------------------------------
When you see premade display in this document,
what is being referred to is a screen that was
made using the Screen Builder program included
with this release of the QBSCR Screen
Routines.
Runtime Library
---------------------------------------------------
A runtime library is a collection of routines
in a special format, like the QBSCR Screen
Routines, that the Microsoft Linker uses to
create your executable program. While a Quick
Library is used to run your programs from
inside the QuickBASIC environment, a runtime
library is used to run your program from DOS,
or outside the QuickBASIC environment.
Selection Bar
---------------------------------------------------
A selection bar is a mechanism used to select
entries from a menu. In a menu, one of the
entries will be highlighted in a color
different from the other entries. It looks
like a bar of a different color has been
placed over the entry, so it is called a
selection bar. Hitting the ENTER key causes
the entry that is currently highlighted by the
selection bar to be returned to the calling
routine.
Shadow (window)
---------------------------------------------------
A shadow is simply a dark edging around two
sides of a window. It creates a 3-D effect,
making the window look like it is sitting away
from the screen.
Window
---------------------------------------------------
A window is an area of the screen that is set
off from the rest in some fashion, usually by
displaying a box around that area. Windows
are excellent tools for isolating ideas on a
common display.
page 7
A Synopsis of the QBSCR Screen Routines
-------------------------------------------------------------
Before we get into the implementation details of
the QBSCR Screen Routines, take a quick look at the
summary of the routines included with the package.
Subprogram BANNER
---------------------------------------------------
This routine will create a scrolling banner on any
line of the screen. The effect is similar to a
Hollywood theater scrolling marquis, advertising
the latest show.
Function BLOCKSIZE
---------------------------------------------------
The BlockSize function is used as a calculation aid
for the BlockSave and BlockRestore subprograms,
listed below. It will calculate the exact number
of elements required for an array to use with
BlockSave and BlockRestore. This function will
prove its value as you begin to use these two
subprograms.
Subprogram BLOCKRESTORE
---------------------------------------------------
The BlockRestore subprogram will restore a
rectangular portion of the screen that was saved
previously with the BlockSave subprogram (below).
Use BlockSave to save part of the screen before
overwriting it (with a window, perhaps), and then
use BlockRestore to replace the portion of the
screen that was overwritten.
Subprogram BLOCKSAVE
---------------------------------------------------
The BlockSave subprogram will save a portion of the
screen that you wish to overwrite and then later
restore (using BlockRestore, above).
Subprogram BUILDSCREEN
---------------------------------------------------
The BuildScreen subprogram will place a premade
display (created with Screen Builder or saved via
GetScreen) onto the screen in any of 16 different
ways. See the DEMO program for a demonstration.
page 8
Subprogram CENTER
---------------------------------------------------
This routine will center any string of 80
characters or less on any specific row of the
screen.
Subprogram CLRSCR
---------------------------------------------------
Designed as a replacement for the CLS statement,
this routine will clear the display screen in any
of 16 different ways.
Function COLORCHK
---------------------------------------------------
This function is used to determine whether the
display the software is running on has color
capability or not. The function returns TRUE
(Non-Zero) if the machine can display color, or
FALSE (Zero) if it cannot.
Function GETBACKGROUND
---------------------------------------------------
This function will return the BASIC color value of
the background color of any location on the screen.
Function GETFOREGROUND
---------------------------------------------------
This function will return the BASIC color value of
the foreground color of any location on the screen.
Subprogram GETSCREEN
---------------------------------------------------
The GetScreen routine will save the current
contents of the display to a disk file, in a format
that is compatible with the BuildScreen and
PutScreen routines, as well as the Screen Builder
program. Save is very fast (< 1 second).
Function GETSTRING
---------------------------------------------------
This function is intended as a replacement for the
BASIC INPUT statement. It will allow the user to
enter a string of text much like INPUT, but with
GETSTRING you can limit the length of the string as
the user enters it. With minor modification of the
source code (change one line), you can limit the
actual characters the user is allowed to enter.
page 9
Function GETVIDEOSEGMENT
---------------------------------------------------
This function returns the starting address of the
video card's display memory. Use before calling
SCRNSAVE or SCRNRESTORE (below) to obtain the
proper address. Easy to use, really! See the DEMO
program for a demonstration if you don't believe
me.
Function MAKEMENU
---------------------------------------------------
This function will create a list-like menu on the
screen and allow the user to choose an entry. The
function returns a numerical value equal to the
chosen entry's position in the list. It provides
two mechanisms to select entries: 1) A scrolling
selection bar, and 2) "Quick Access" keys. Both
mechanisms are implemented simultaneously. See the
DEMO program for a demonstration.
Subprogram MAKEWINDOW
---------------------------------------------------
This versatile routine will create windows on the
screen for you. It will display 10 different
window types, 6 different frame types, can explode
windows onto the screen in 3 modes, add window
shadows, and more.
Subprogram MULTIMENU
---------------------------------------------------
The MultiMenu subprogram will create a multiple
menu, pull-down menu interface for your programs,
very much like the pull-down menus in the
QuickBASIC environment. Easy to set up and use.
Subprogram OFFCENTER
---------------------------------------------------
Allows you to center text between two columns on a
line that are not necessarily centered themselves
with respect to the screen. For instance, if you
placed a window on the right side of the screen,
simply tell OFFCENTER the sides of the window, and
it will center text between those two columns.
Subprogram PUTSCREEN
---------------------------------------------------
This routine will load from disk a premade display
that was created with either the GetScreen routine
(above) or the Screen Builder program. Load and
display is very fast (< 1 second).
page 10
Subprogram QBPRINT
---------------------------------------------------
This routine will place a text string on the
display at the position specified in the color
specified. Unlike the PRINT statement, QBPrint
writes directly to video memory and will display
characters like ASCII 7, the round bullet, and
others as well.
Function SCREENBLANK
---------------------------------------------------
This function, when called, blanks the screen of
your display, and shows a short message explaining
that the screen has been blanked. When a key is
pressed, ScreenBlank terminates and control is
returned to the calling routine. To prevent the
short message from "burning-in" to the monitor, it
changes place periodically. This function returns
the key that was pressed to restore the display, in
case you want to use it.
Subprogram SCRNRESTORE
---------------------------------------------------
This routine will restore all or a portion of the
display that has been saved with the SCRNSAVE
routine. When used with SCRNSAVE, this routine
provides unbeatable results.
Subprogram SCRNSAVE
---------------------------------------------------
This routine will save a portion or all of the
current display screen. When used in conjunction
with the SCRNRESTORE routine, SCRNSAVE provides the
capability to "pop" parts of a display, like
windows, error messages, menus, etc., to and from
the screen.
Subprogram WIPE
---------------------------------------------------
This routine clears out a programmer-defined
portion of the display. Excellent for erasing the
text from windows.
page 11
The SCREEN BUILDER Program
-------------------------------------------------------------
Screen Builder is a new companion program to the
QBSCR Screen Routines. With the introduction of
BuildScreen in version 1.4, it was realized that
the concept of placing a premade screen on the
display in interesting ways was a nifty idea. The
problem was in its implementation. Dealing with an
array of 25 lines was unwieldy at best. Neither was
it acceptable to be dealing only with two colors.
Enter Screen Builder.
Screen Builder is an interactive screen editor. It
will allow you to easily create multicolor text
screens as complicated or as simple as you like.
It has tools to let you enter extended ASCII
graphics characters, perform block operations, and
lots of other goodies. It saves your screen files
in a format specific to BASIC, and allows the
BuildScreen (and PutScreen) routines to access your
screen files.
Now with Screen Builder, you can quickly and easily
create attractive screens for your programs, and
display them quickly (using PutScreen) or in an
interesting way (using BuildScreen). Tools like
Screen Builder have sold for much more by
themselves. It is included as part of the QBSCR
Screen Routines package.
For detailed information on the capabilities and
usage of Screen Builder, refer to the Screen
Builder documentation.
page 12
The DEMO Program
-------------------------------------------------------------
Included with the QBSCR package is a program called
DEMO. Source code for the program is included as
well.
DEMO is a demonstration program that illustrates
the use of each of the routines in the QBSCR Screen
Routine library. One of the best learning
techniques for using the Screen Routines is to
execute this program, and as it runs, follow along
in the source code to see what's happening and how
it's being done.
To run the DEMO program, make sure that the file
DEMO.EXE and all the *.CLR or *.MON files (CLR if
you have a color display, MON if you have a mono
display) are in the same place (i.e., the same
drive and subdirectory). Then enter the following
command at the DOS prompt:
DEMO
The program will begin executing and you can see in
the source code what's happening. Simply follow
the on-screen directions.
The source code for DEMO is fully documented and
can even be used as a quick reference on the syntax
of each routine. A good thing to keep handy as you
program.
page 13
The REF Program
-------------------------------------------------------------
The QBSCR Screen Routines are packaged with a free
program called REF. REF is a computer-based tool
that can be used as a reference to the
often-looked-up portions of the Screen Routines. It
will tell you all the window types, frame types,
and explode types for the MakeWindow routine, as
well as all ClrScr and BuildScreen modes. Source
code for REF is also included with QBSCR.
To run REF, make sure the files REF.EXE and
TESTSCR.* are in the same place (i.e., the same
drive and subdirectory), and issue the following
command at the DOS prompt:
REF
The program will execute and you will see its menu.
To select one of the menu entries, use the arrow
keys to highlight the selection of your choice, and
hit ENTER. Notice, however, that each menu entry
has a single letter within it highlighted. This is
the "Quick Access" key for that menu entry. You
may use the "Quick Access" keys by hitting the
highlighted letter associated with the selection of
your choice. Each REF function is detailed below.
Window Types
---------------------------------------------------
The Window Types function will display all the
possible values of the WindowType parameter for the
MakeWindow subprogram. Select this function from
the menu by highlighting it with the selection bar
and hitting ENTER, or hitting the W "Quick Access"
key. REF will then show you a screen with ten
different windows and some explanatory text. Within
each window is a number which corresponds to the
value used for the WindowType parameter that will
create that type of window. Once you've finished
looking over the information, you can return to the
menu by hitting any key.
Frame Types
---------------------------------------------------
Frames are what define or draw your windows. On
the IBM PC and its derivatives, you can have
several combinations of single and double line
frames. This function of REF will show you what
value of the FrameType parameter will result in
what type of frame. Select this function from the
page 14
menu by highlighting it with the selection bar and
hitting ENTER, or hitting the F "Quick Access" key.
REF will then show you a screen displaying the six
possible frame types and the FrameType parameter
values used to attain them. Once you've finished
looking over the information, you can return to the
menu by hitting any key.
Explode Types
---------------------------------------------------
The Explode Type parameter of the MakeWindow
subprogram defines how your window will be placed
on the screen. You can simply have it drawn
normally, or have it "exploded" onto the screen in
one of several ways. This portion of REF
demonstrates the three Explode Types and tells you
which parameter value corresponds to which explode
type. Select the Explode Type function of REF from
the menu by highlighting it with the selection bar
and hitting the ENTER key, or hitting the E "Quick
Access" key. REF will demonstrate the three
explode types with sample windows on the screen.
Simply follow the on-screen directions. Once REF
has shown you the last explode type, you may return
to the menu by hitting any key.
ClrScr Modes
---------------------------------------------------
The ClrScr function will clear your screen in any
of sixteen different modes. Each mode clears the
screen in a different way, resulting in a different
sort of "animation". This function of REF will
demonstrate any of the sixteen modes. Select the
ClrScr Modes function of REF from the menu by
highlighting it with the selection bar and hitting
ENTER, or by hitting the C "Quick Access" key. You
will then see the screen filled with the ASCII 176
character (a shaded rectangle), and a small window
in the center of the screen. In this window, enter
a number from 0 to 15 (inclusive), indicating which
ClrScr mode you would like to see. Once you hit
the ENTER key, REF will demonstrate the ClrScr mode
you indicated and then pause. You can then try
another mode by hitting any key. REF will fill the
screen again and allow you to enter another mode.
If you have finished with the ClrScr Modes
function, you can return to the menu by hitting the
ESC key.
BuildScreen Modes
---------------------------------------------------
The BuildScreen function will place on the screen
an array of strings that define a display. It will
place your display on the screen in any of sixteen
different modes. Each mode displays the screen in
page 15
a different way, resulting in a different sort of
"animation." This function of REF will demonstrate
any of the sixteen modes. Select the BuildScreen
Modes function of REF from the menu by highlighting
it with the selection bar and hitting ENTER, or by
hitting the B "Quick Access" key. You will then
see a blank screen with a small window in the
center of the screen. In this window, enter a
number from 0 to 15 (inclusive), indicating which
BuildScreen mode you would like to see. Once you
hit the ENTER key, REF will demonstrate the
BuildScreen mode you indicated, and then pause.
You can then try another mode by hitting any key.
REF will clear the screen again and allow you to
enter another mode. If you have finished with the
BuildScreen Modes function, you can return to the
menu by hitting the ESC key. NOTE: The BuildScreen
portion of REF requires access to the file
TESTSCR.CLR (or .MON). This file must be in the
same place (i.e., same drive and subdirectory) as
the REF program before you start REF, or the
program will terminate ungracefully.
Quit REF
---------------------------------------------------
Once you have returned to the menu from whatever
REF functions you needed to use, you may quit the
REF program by highlighting the Quit function with
the selection bar and hitting ENTER, or by hitting
the Q "Quick Access" key. The screen will clear
and you will be returned to DOS.
page 16
The COLCONST.BAS File
-------------------------------------------------------------
Included with the QBSCR Screen Routines is a short
file of BASIC code that will make your programming
of colors much easier. It's called COLCONST.BAS,
which is short for COLOR CONSTANTS.
What it consists of is a collection of CONSTant
declarations that assign color values to names.
For example, two of the lines look like this:
CONST BLACK = 0
CONST MAGENTA = 5
This would allow you to issue a color statement
that looks like this:
COLOR MAGENTA, BLACK
This will improve the readability of your code
immensely, while also making it easier to code
colors into your program. There are also constants
for the BRIGHT and BLINK attributes that you can
combine with the colors, as in this example that
produces a blinking Blue on a White background:
COLOR BLINK + BLUE, WHITE
or this example that makes bright White on a Red
background:
COLOR BRIGHT + WHITE, RED
There is also a predefined color called YELLOW, so
you don't have to say BRIGHT + BROWN. Just use
YELLOW.
To incorporate these useful constants in your
program, simply use the QuickBASIC MERGE command
from the File menu...
1. Place the cursor at the beginning of
your program...
2. Select the QuickBASIC File menu...
3. Select the MERGE function...
4. Enter COLCONST.BAS in the file field
and hit ENTER.
The code for the color constants will be merged
into your program for easy use.
page 17
Incorporating the Screen Routines
into Your Own Programs
-------------------------------------------------------------
There are several ways you can use the QBSCR Screen
Routines with your own programs. Each method has
its advantages and drawbacks. You must decide
which method is best for you based on your needs.
Each method is detailed below, as well as its pros
and cons.
Method 1: MERGE
---------------------------------------------------
The QuickBASIC editor has a MERGE function on its
Edit menu. Using this function, you can easily
merge the source code file (QBSCR.BAS) into your
own program. Once there, you can delete the
routines you don't plan to use in your program.
Before you go through wantonly deleting routines,
however, make sure that you check the QBSCR cross
reference in the back of this manual, to make sure
you aren't deleting a routine that another routine
depends on. By merging, the routines become a
permanent part of your program. The benefits are
that you don't have to worry about additional files
when moving the source code of your program, and
you can neatly tailor the screen routines to suit
the needs of your particular program. The main
drawback is that you are reducing the possible size
of your own source code by the size of the screen
routines. QuickBASIC has a limited amount of space
available for such things as strings and dynamic
arrays. The more source code you have in your main
module, the more likely it becomes that you will
have to go to multiple modules. This isn't bad,
but it defeats the purpose of merging the QBSCR
routines into your own program. This method is
recommended if your program will not be too large.
To actually perform the merge, start QuickBASIC and
load your own source code if necessary. Then
select the File menu, and the Merge option. You
will be allowed to pick from a menu or enter a name
manually. Select or enter
QBSCR.BAS
and the routines will be merged into your program.
All the DECLARE statements from the Screen Routines
will be placed in your program wherever you had the
cursor when you performed the merge, so make sure
the cursor is where you want the DECLARE
statements. You may now call any of the screen
page 18
routines you like, delete any of the ones you won't
be needing, or change them to suit your needs.
Method 2: LOAD
---------------------------------------------------
The LOAD method is similar to the MERGE method, but
the QBSCR routines don't become a permanent part of
your own program. Using this method, you load the
QBSCR Screen Routines source code (QBSCR.BAS) as a
separate file. When your program is saved,
QuickBASIC will create a .MAK file, which contains
the names of all files in memory when the program
was saved. QuickBASIC then uses this file to tell
it what files to load when you open your program.
Advantages of this method are that you have more
available memory for your own source code and the
Screen Routines are kept in a separate "package" or
file which aids program clarity. You can delete or
change the QBSCR routines as easily as with the
MERGE option above (but make SURE you are working
with a COPY of the QBSCR.BAS file, as the changes
you make become permanent). Problems with this
method are mostly convenience-oriented. Loading
your program into QuickBASIC, compiling your
program, and execution of your program (inside the
environment ONLY) are all slower than the next
method, using the Quick Library.
To load the QBSCR Screen Routines using this
method, start QuickBASIC and load your own program
if necessary. Then select the File menu, and the
Load option. You will then be able to either
select from a list or enter the name manually.
Enter
QBSCR.BAS
and QuickBASIC will load the file as a separate
module. Once this is done, you can see QBSCR and
all its routines by hitting the F2 key. To use the
routines, you will need to make sure your program
has all the appropriate DECLARE statements from the
Screen Routines. You can either copy the DECLARE
statements from the QBSCR module over to your own
program using the environment editor, or you can
place the following statement at the top of your
own program:
REM $Include: 'QBSCR.INC'
This will cause the compiler to load the file
QBSCR.INC into your module at compile time. This
file contains all the DECLARE statements for the
QBSCR Screen Routines. The file must be in the
same drive and subdirectory as QuickBASIC.
page 19
You can now use any or all of the Screen Routines,
delete the ones you don't need, or change them to
suit your needs. If you copy your source code to
another disk or subdirectory, don't forget to copy
the files QBSCR.BAS, QBSCR.INC (if you used the
$Include statement above), and the .MAK file for
your program.
Method 3: Use the Quick Library
---------------------------------------------------
To use the Quick Library method, you must have a
Quick Library form of the QBSCR routines. To
create the QuickLibrary for the QBSCR Screen
Routines, load QBSCR.BAS into QuickBASIC by itself.
Then choose the "Make Library" option from the Run
menu. QuickBASIC will then go through a normal
compile, and then create two library files. The 2
files generated, QBSCR.QLB and QBSCR.LIB, need to
be on the same drive and in the same subdirectory
as QuickBASIC. Using this method, you start
QuickBASIC with a /L parameter, followed by the
library to use. Advantages are mostly convenience
oriented. They include faster loading, compiling,
linking and environment-execution of your program.
The primary disadvantage is that you cannot modify
the QBSCR routines in any way from the environment.
To use the QBSCR Screen Routines in the Quick
Library format, start QuickBASIC using the
following command (where you would replace MYPROG
with the actual name of your program):
QB MYPROG /L QBSCR
This will cause QuickBASIC to load your program
along with the Quick Library QBSCR. Once inside
the QuickBASIC environment, you will also need to
make sure your program has all the appropriate
DECLARE statements from the Screen Routines. You
can place the following statement at the top of
your own program:
REM $Include: 'QBSCR.INC'
This will cause the compiler to load the file
QBSCR.INC into your module at compile time. This
file contains all the DECLARE statements for the
QBSCR Screen Routines. The file must be in the
same drive and subdirectory as QuickBASIC.
Your program now has access to all of the QBSCR
Screen Routines.
page 20
Summary of Incorporation Methods
---------------------------------------------------
It has been my experience that method 2, LOAD, is
the most generally useful of the three methods. Use
method 1, MERGE, if your program will be small to
medium sized. Use method 3, the Quick Library, if
you are in a particular hurry to develop your
program, as it loads and compiles faster, as well
as executing inside the environment faster.
As far as the final standalone executable program
is concerned, all three methods create equally fast
code. The first two methods may be better if
executable size is important to you, as you can
edit out the routines your program doesn't actually
use.
page 21
The QBSCR Routines Detailed Descriptions
-------------------------------------------------------------
We are about to enter the detailed descriptions of
each of the QBSCR Screen Routines, and I thought I
might warn you what to expect.
For each of the routines, the following information
will be provided:
■ The NAME of the routine
■ The PURPOSE of the routine
■ The USAGE of the routine
■ A description of each PARAMETER the routine
requires
■ A DESCRIPTION of the routine, including any
relevant notes
■ An EXAMPLE of the use of the routine
■ Any known limitations of the routine
Each routine and it's related information will be
presented on it's own page. If the description
runs over onto a second or third page, the next
routine description will start on a new page. This
will help keep things organized and easy to deal
with.
page 22
Subprogram BANNER
-------------------------------------------------------------
Purpose: To create a scrolling banner effect with a
single string on any line of the display.
Usage: Banner st$, row%
st$ - the text string to make into a
banner.
row% - the row of the screen on which to
make the banner.
Details: The Banner routine will not create a
scrolling banner with a single call. The scrolling
effect is achieved through continuous calls to the
routine. A single call to Banner will:
1) Remove the first letter from the left end
of the string,
2) Shift all remaining characters one position
to the left,
3) Place the first letter it removed in step 1
onto the right tail end of the string, and
4) Center the string on the display at the
requested row.
Thus, the single call will shift the string by one
character and redisplay it. To see how to
implement the continuous scrolling effect, see the
example below.
Example: The string we will use in our example is
called bannerString$, and we will display it on the
12th (middle) row of the screen. This routine will
continue to scroll the banner until a key is
pressed.
' Banner example begins
bannerString$ = "The Marvelous Screen Routines"
DO
Banner bannerString$, 12
LOOP UNTIL INKEY$ <> ""
' Banner example ends
page 23
Known Limitations: The Banner routine relies on the
STATIC statement at the end of its declaration to
maintain its position in the string between calls.
This means that you can only call the Banner
routine for one string per program. If you want to
display more than one banner in your program, or a
different banner with different text, this routine
isn't for you.
page 24
Function BLOCKSIZE
-------------------------------------------------------------
Purpose: To calculate the number of elements
required for an array that will be used to save a
rectangular portion of the screen, via the
BlockSave routine (below).
Usage: Right inside of a DIM statement, such as
DIM blockArray%(BlockSize%(l%, r%, t%, b%))
l% - left column of area to save
r% - right column of area to save
t% - top row of area to save
b% - bottom row of area to save
Details: This routine is useful when saving and
restoring parts of the screen using the BlockSave
and BlockRestore routines (below). You will need
to know how big to dimension the array that will
hold the screen information, and this function will
calculate the exact number of elements required.
You could dimension an array to 4000 elements to
cover all cases, but that would be wasteful of
memory. BlockSize makes your programs efficient.
To use the function, you can assign its value to a
variable, and then use the variable as the argument
in your DIM statement, or you could be even more
efficient and place the BlockSize function directly
into your DIM statement, as shown above in the
Usage. Simply fill in the parameters for the left,
right, top, and bottom sides of the rectangular
area you want to save, and BlockSize does the rest.
Example: The example below uses BlockSize to
dimension a variable called sArray%(), and then
calls upon BlockSave to save the area of the
screen.
' BlockSize example begins
' Dimension an array to hold screen information
DIM sArray%(BlockSize%(1, 15, 1, 10))
' Save the area of the screen
BlockSave 1, 15, 1, 10, sArray%(), GetVideoSegment
' BlockSize example ends
Known Limitations: None.
page 25
Subprogram BLOCKRESTORE
-------------------------------------------------------------
Purpose: To restore a rectangular area of the video
display that was previously saved using BlockSave
(below).
Usage: BlockRestore l%, r%, t%, b%, scrArray%(),
segment!
l% - left column of area to restore
r% - right column of area to restore
t% - top row of area to restore
b% - bottom row of area to restore
scrArray%() - the array in which screen
information was saved
segment! - the memory segment of the
display memory. Use the
function GetVideoSegment for
this
Details: This routine is to be used to restore a
portion of the video display that has previously
been saved using the BlockSave function (below).
Once you have finished with the portion of the
display you had previously saved, make a call to
this routine and it will restore what was saved.
This routine is essentially a more efficient
version of the ScrnRestore routine, also part of
the QBSCR Screen Routines. ScrnSave and
ScrnRestore are provided to maintain upward
compatibility from previous versions of the Screen
Routines. This should be the preferred routine to
use when saving and restoring PORTIONS of the
screen.
Make sure when you call this routine that you use
the same coordinates that you used on the BlockSave
call, or you will get a "Subscript Out of Range"
error at runtime.
For more information regarding the screen save and
restore process, see the BlockSave subprogram
below, and the section of this manual titled
"Displaying and Popping a Window."
Example: The example below goes through all the
steps necessary to allocate (DIMension) an array in
which to save a portion of the screen, saving, and
then restoring the display.
page 26
' BlockRestore example begins
' Dimension an array to hold the screen information
DIM s%(BlockSize%(1, 15, 1, 10))
' Save the rectangular area of the screen
BlockSave 1, 15, 1, 10, s%(), GetVideoSegment
' At this point you could overwrite the portion of
' the display that was saved, with a window or
' perhaps a menu. Once you are finished with the
' part of the display that was overwritten, you
' would restore what was there in the first place,
' like this:
' Restore the saved portion of the display
BlockRestore 1, 15, 1, 10, s%(), GetVideoSegment
' BlockRestore example ends
Known Limitations: None.
page 27
Subprogram BLOCKSAVE
-------------------------------------------------------------
Purpose: To save a rectangular area of the video
display so that it may be restored using
BlockRestore (above) after being overwritten.
Usage: BlockSave l%, r%, t%, b%, scrArray%(),
segment!
l% - left column of area to save
r% - right column of area to save
t% - top row of area to save
b% - bottom row of area to save
scrArray%() - the array in which screen
information will be saved
segment! - the memory segment of the
display memory. Use the
function GetVideoSegment for
this
Details: If you need to display a window or other
information on top of your existing display, you
can use BlockSave (and subsequently BlockRestore)
to do it. Just save the portion of the screen you
are going to be overwriting with BlockSave, then
display whatever you need in the saved area. Once
you are done with the area, and need the old info
back on-screen, use BlockRestore to get it back.
For more information on this technique, see the
section of this manual titled "Displaying and
Popping a Window."
This routine is essentially a more efficient
version of the ScrnSave routine, also part of the
QBSCR Screen Routines. ScrnSave and ScrnRestore
are provided to maintain upward compatibility from
previous versions of the Screen Routines. This
should be the preferred routine to use when saving
and restoring PORTIONS of the screen.
Make sure when you call the BlockRestore routine
that you use the same coordinates that you used on
the BlockSave call, or you will get a "Subscript
Out of Range" error at runtime.
Example: The example below goes through all the
steps necessary to allocate (DIMension) an array in
which to save a portion of the screen, saving, and
then restoring the display.
page 28
' BlockRestore example begins
' Dimension an array to hold the screen information
DIM s%(BlockSize%(1, 15, 1, 10))
' Save the rectangular area of the screen
BlockSave 1, 15, 1, 10, s%(), GetVideoSegment
' At this point you could overwrite the portion of
' the display that was saved, with a window or
' perhaps a menu. Once you are finished with the
' part of the display that was overwritten, you
' would restore what was there in the first place,
' like this:
' Restore the saved portion of the display
BlockRestore 1, 15, 1, 10, s%(), GetVideoSegment
' BlockSave example ends
Known Limitations: None.
page 29
Subprogram BUILDSCREEN
-------------------------------------------------------------
Purpose: To place a predefined display on the
screen in an interesting fashion.
Usage: BuildScreen file$, mode%
file$ - the file that is the premade
display to be put on the screen.
mode% - Specifies the manner in which the
screen is to be placed on the
display. Value must be in the
range 0 through 15. See the REF
program for a demonstration of
each mode%.
Details: To use BuildScreen, your premade display
must have been created either with the GetScreen
routine or the Screen Builder program. See the
section of this manual entitled "The SCREEN BUILDER
Program," or the Screen Builder documentation for
more information.
To have BuildScreen display one of your premade
screens, you must tell it
1. The file that contains the screen, and
2. The display mode to use when placing it
on the screen.
There are 16 different ways that BuildScreen can
display your screen. To see all of them, run the
REF program that accompanies this package and
select the BuildScreen modes from the main menu.
Then follow the onscreen instructions.
This routine can provide some wonderful special
effects for your program. The most immediate use
for BuildScreen I can see is for the opening screen
of your program. You can just as easily generate
any kind of ASCII multicolor text display you need,
for data entry screens, premade windows or info
screens, or whatever.
page 30
Example: In the example below, we will be placing
on the screen a premade display stored in a file
called DISPLAY.CLR. The BuildScreen mode will be
15.
' BuildScreen example begins
' Assign a BuildScreen mode%
buildMode% = 15
' Assign a filename
file$ = "DISPLAY.CLR"
' Build the screen with BuildScreen
BuildScreen file$, buildMode%
' BuildScreen example ends
Known Limitations: None.
page 31
Subprogram CENTER
-------------------------------------------------------------
Purpose: To center any string of text in a row of
the screen specified by the programmer.
Usage: Center st$, row%
st$ - The string to center on the screen
row% - The row of the screen to center
the text on. Must be from 1 to 25
Details: This routine is very simple to use. Tell
it the string you want to center on the screen and
the row of the screen you want it on. The string
must be less than or equal to 80 characters in
length.
Example: This example is very straight-forward.
It will center the string provided to the routine
call as a literal string (not a variable), on the
row specified (in this case, row 3).
' Center example 1 begins
Center "A string to center on the screen", 3
' Center example 1 ends
You could also use variables if you like, as in the
example 2 below:
' Center example 2 begins
string$ = "A string to center on the screen"
row% = 3
Center string$, row%
' Center example 2 ends
Known Limitations: None.
page 32
Subprogram CLRSCR
-------------------------------------------------------------
Purpose: To clear the display screen in interesting
ways.
Usage: ClrScr mode%, fillchar$
mode% - Specifies the manner in which
the display is cleared. Has
16 predefined modes. Value
must be in the range 0 - 15.
fillchar$ - The character to clear the
screen with. Will usually be
a space.
Details: The ClrScr routine provides interesting
ways of clearing the screen inside your program.
One thing to remember is that if you want to clear
the screen so that it is black, set the screen
colors to something with a black background BEFORE
calling ClrScr. It assumes that you have the
colors set how you want them. For a demonstration
of all the ClrScr modes, run the REF program.
Note also that the ClrScr modes correspond to the
BuildScreen modes.
Example: The following example will clear the
display screen using ClrScr mode 15.
' ClrScr example begins
clrMode% = 15
fill$ = " "
ClrScr clrMode%, fill$
' ClrScr example ends
Known Limitations: ClrScr mode 15 is a tad slow
toward the end of the clear sequence.
page 33
Function COLORCHK
-------------------------------------------------------------
Purpose: To determine if the host machine has color
display capability.
Usage: As a function that returns a true or false
value in a logical expression. See example for
more information.
Details: The COLORCHK function will return a value
of TRUE (non-zero) if the machine it is executed on
has the capability to display color. It will
return FALSE (zero) if the machine is monochrome
only. Use it in a logical expression to determine
the colors you should use in your program.
Example: The example below demonstrates the usage
of COLORCHK to set the colors before displaying
some text. Once it is known whether or not the
machine can display color, you can set the colors
appropriately.
' ColorChk example begins
IF ColorChk THEN
COLOR 14, 4 'Yellow on Red -ColorChk is TRUE
ELSE
COLOR 7, 0 'White on Black -ColorChk is FALSE
END IF
PRINT "This text will be in the right color."
' ColorChk example ends
Known Limitations: The function will determine only
if color capability is available. It will not
determine the specific graphics adapter installed.
page 34
Function GETBACKGROUND
-------------------------------------------------------------
Purpose: To determine the background color of any
specified location on the display screen.
Usage: As a function that returns an integer value
that is a valid BASIC background color (0-7).
background% = GetBackground%(row%, col%)
row% - the row portion of the coordinate
to return a background value for
col% - the column portion of the
coordinate to return a background
value for
Details: If you need to know the background color
of any character on the screen, use this function
to obtain it. Used in combination with the
GetForeground function, the complete colors of any
spot on the screen can be determined.
The row and column parameters are passed to the
function to tell it exactly which screen location
for which you want the background color. It will
return a value from 0 to 7, indicating the
background color of the specified character cell.
Example: The example below will obtain the
background color for the character cell at row 10,
column 20.
' GetBackground example begins
' Assign the background color to the variable
' called background%
background% = GetBackground (10, 20)
' GetBackground example ends
Known Limitations: None.
page 35
Function GETFOREGROUND
-------------------------------------------------------------
Purpose: To determine the foreground color of any
specified location on the display screen.
Usage: As a function that returns an integer value
that is a valid BASIC foreground color (0-31).
foreground% = GetForeground%(row%, col%)
row% - the row portion of the coordinate
to return a foreground value for
col% - the column portion of the
coordinate to return a foreground
value for
Details: If you need to know the foreground color
of any character on the screen, use this function
to obtain it. Used in combination with the
GetBackground function, the complete colors of any
spot on the screen can be determined.
The row and column parameters are passed to the
function to tell it exactly which screen location
for which you want the foreground color. It will
return a value from 0 to 31, indicating the
foreground color of the specified character cell.
Example: The example below will obtain the
foreground and background colors for the character
cell at row 10, column 20.
' GetForeground example begins
' Assign the foreground and background color to the
' variables called foreground% and background%
foreground% = GetForeground (10, 20)
background% = GetBackground (10, 20)
' GetForeground example ends
Known Limitations: None.
page 36
Subprogram GETSCREEN
-------------------------------------------------------------
Purpose: Will save the contents of the screen
display to a disk file.
Usage: GetScreen file$
file$ - the file in which the display
contents will be saved.
Details: This routine will save the contents of the
video display to a disk file. While there probably
won't be much call for this routine, it can be used
whenever a screen capture capability is required.
Note that this routine is the heart of the Screen
Builder's Save function.
Example: This example will save the contents of the
display to a disk file called SAVED.SCR.
' GetScreen example begins
' Save display contents to a file
GetScreen "SAVED.SCR"
' GetScreen example ends
Known Limitations: Will save screen information
only in the binary BASIC format.
page 37
Function GETSTRING
-------------------------------------------------------------
Purpose: To obtain string input from the user while
limiting the length of the string the user enters
as they enter it.
Usage: st$ = GetString$(lCol, row%, lngth%, f%, b%)
st$ - Any variable name to which the
user's entry will be assigned
when they have completed entry.
lCol - The left-most column to begin
begin displaying the user's
entry on as they type.
row% - The row of the screen to display
the user's entry on as they
type.
lngth% - The maximum length of the string
the user is allowed to enter.
f% - The foreground color in which to
display the user's entry.
b% - The background color in which to
display the user's entry.
Details: While the user is typing in an entry, they
may use the backspace key to correct errors. Once
the user has finished entering characters, they
will hit the ENTER key to signify that they are
finished. If the user hits the ESC key, then ASCII
27 (Escape) will be immediately returned by the
GetString function. You can test for the ESC
character and act as you see fit. Try hitting the
ESC key in the DEMO program, or look at the DEMO
source code to see how it handles the ESC key.
You can easily modify the source code for this
function to limit the characters the user is
allowed to enter. The current range is ASCII 32
through 254. Simply change the line in the CASE
statement in the source code to suit your needs.
For example, if you wanted the user to only be
allowed to enter numbers, you could change the case
statement to read
CASE "0" TO "9"
and the CASE ELSE will take care of extraneous
illegal input.
page 38
Example: This example will use the GetString
function to accept an eight-character filename from
the user. If the user hits the ESC key, a message
will be printed and the example will end. The
entry will be at the 10th column of row 5, and will
be in reverse video (Black on White).
' GetString example begins
CONST FALSE = 0, TRUE = NOT FALSE
lCol% = 10: row% = 5
entryOK = FALSE
DO
st$ = GetString$(lCol%, row%, 8, 0, 7)
SELECT CASE st$
CASE CHR$(27) ' The ESC key
LOCATE 6, 10
PRINT "User hit ESC!"
entryOK = TRUE
CASE "" ' User simply hit ENTER
LOCATE 6, 10
PRINT "Try that again..."
CASE ELSE ' Assume correct entry
entryOK = TRUE
END SELECT
LOOP UNTIL entryOK
' GetString example ends
Known Limitations: The only editing key provided is
the backspace key. Future versions of the QBSCR
will add more editing keys, like Home, End, etc.
Feel free to add your own.
page 39
Function GETVIDEOSEGMENT
-------------------------------------------------------------
Purpose: Returns the proper memory address of the
video card display memory. Used with the SCRNSAVE
and SCRNRESTORE routines, the BLOCKSAVE and
BLOCKRESTORE routines, and internally by some of
the routines.
Usage: segment = GetVideoSegment
- or as part of an expression or parameter
list. See example below.
Details: This function is used primarily for the
SCRNSAVE and SCRNRESTORE (also BlockSave and
BlockRestore) functions. These routines require
knowledge of the location of the video display
card's memory. This function provides it. It is
necessary because the display memory for color
video starts at an address different from that of
monochrome video.
There are two ways to use this function. You may
either assign the result of this function to a
variable, as in the usage above, or you can place
the function name directly in the SCRNSAVE and
SCRNRESTORE (also BlockSave and BlockRestore)
function parameter list. The examples below will
demonstrate both usages. The first method will
result in slightly faster execution of your
program, yet requires the use of an additional
variable. The second method is easier and does not
require the use of a second variable, but may run
slower, since the function will be evaluated every
time it is used.
Example: The following examples will demonstrate
the same thing - using GETVIDEOSEGMENT to provide
information to the SCRNSAVE routine. It is assumed
that the array scrArray%() has been allocated
(DIMensioned) already.
' GetVideoSegment example 1 begins
segment = GetVideoSegment
ScrnSave 1, 25, scrArray()%, segment
' GetVideoSegment example 1 ends
page 40
' GetVideoSegment example 2 begins
ScrnSave 1, 25, scrArray()%, GetVideoSegment
' GetVideoSegment example 2 ends
Known Limitations: None.
page 41
Function MAKEMENU
-------------------------------------------------------------
Purpose: To produce a menu on the screen and return
a user's selection.
Usage: s% = MakeMenu%(choices$(), numOfChoices%,
justify$, leftCol, rightCol,
row%, marker$,
fg%, bg%, hfg%, hbg%,
qfg%, qbg%)
s% - Any integer variable that will
hold the number of the user's menu
selection.
choices$() - An array of strings that
are the choices to be displayed in
the menu list.
numOfChoices% - The number of choices
available in the menu.
justify$ - A single letter (L, R, or C)
indicating the type of text
justification to use when placing
the menu entries on the screen.
L = Left, R = Right, C = Centered.
leftCol% - The left-most column to
consider when placing the menu
entries on the screen.
rightCol% - The right-most column to
consider when placing the menu
entries on the screen.
row% - The first row of the screen to
begin placing menu entries on.
marker$ - The character used to tell
MakeMenu that the next character
in the entry is a Quick Access key
fg% - The foreground color of normal
menu entries.
bg% - The background color of normal
menu entries.
hfg% - The foreground color of a menu
entry highlighted by the selection
bar.
hbg% - The background color of a menu
entry highlighted by the selection
bar.
qfg% - The foreground color of a menu
entry's "Quick Access" key.
qbg% - The background color of a menu
entry's "Quick Access" key.
page 42
Details: The MakeMenu function will create on the
screen a vertical list of choices. The user may
select one of the entries, the number of which will
be returned by the function.
The user has two mechanisms available to select one
of the menu entries. The first is the selection
bar. This is a colored bar that moves from entry
to entry via the arrow and related keys. The
following table describes the actions possible with
the selection bar in the menu, and which keys
perform these actions:
Menu Action... ...is Performed By
---------------------------------------------------
Move selection bar DOWN 1 entry Down Arrow
Move selection bar UP 1 entry Up Arrow
Move selection bar to top of list PgUp, Home
Move selection bar to bottom of list PgDn, End
Select the currently highlighted entry ENTER
Abort menu selection process ESC
There is a second mechanism available to the user
if you choose to implement it in your menu. This
is the use of "Quick Access" keys. A Quick Access
key is a single unique letter of each menu entry
that can be used to immediately select that entry.
If you had a menu entry called Quit, you could
specify the Q as a Quick Access key. In this way,
the user could hit the Q key to quit immediately,
instead of having to move the selection bar to the
Quit entry and press ENTER. Implementing the Quick
Access keys in your own menus is extremely simple.
To make the process of creating a menu more clear,
let's step through the process of setting one up.
All the text of the menu entries is stored in an
array. You must dimension an array with the number
of entries in your menu, as in this example:
numOfChoices% = 4
DIM choices$(numOfChoices%)
This would allow us four menu entries, or four
selections available to the user. The next step
would be to assign the text to each element of the
array, as in the following hypothetical example:
choices$(1) = "Load File"
choices$(2) = "Edit File"
choices$(3) = "Save File"
choices$(4) = "Quit"
At this point you may choose to implement the use
of the Quick Access keys. Simply decide which
letter in each entry will be your Quick Access key
page 43
for that entry. Each letter must be unique. In
our above example, since the first letter in each
entry is unique, we can use the first letter of
each entry as my Quick Access key for that entry.
The trick is, how do we tell MakeMenu which
character to use? This is where the marker$
parameter comes in. Select an obscure unused
character (I always use the ^ character) and pass
it to MakeMenu in the right place. Then, simply
imbed this marker character (in our case the ^
character) right BEFORE the letter you want to use
as the Quick Access key. Below are our menu entries
redone to implement Quick Access keys:
marker$ = "^"
choices$(1) = "^Load File"
choices$(2) = "^Edit File"
choices$(3) = "^Save File"
choices$(4) = "^Quit"
This would allow the user to hit the L key to Load
a file, the E key to Edit a file, the S key to Save
a file, and the Q key to Quit. Since the letters
L, E, S, and Q are unique, we are all set. The
MakeMenu function takes care of all the details.
All you had to do was tell it which letters to use.
When the menu entries are displayed on the screen,
the Quick Access keys will be highlighted in a
different color (the color specified by the qfg%,
and qbg% parameters you passed to MakeMenu). If
you don't want to implement the Quick Access keys,
simply do not imbed any marker characters. Make
sure you pass an unused marker$ character to
MakeMenu, though.
The next step would be to decide what type of
justification to use when the entries are displayed
on the screen. You may use left, right, or
centered justification. The placement will be
relative to the left and right columns you send to
MakeMenu. Tell MakeMenu what type of justification
to use via the justify$ parameter. This variable
holds a single letter, either an L, R, or C, for
Left, Right, or Centered, respectively. In our
example we will use Left justification, so our
justify$ parameter will be L, as below:
justify$ = "L"
Now you must decide where on the screen you want
your menu. We will center our menu in the middle
of the screen. The first row to begin placing the
menu entries on would be 11. The left-most column
that would result in our entries being roughly in
the middle of the screen is 36, while the
page 44
right-most column would be 45. Set our parameters
row%, leftCol, and rightCol to these values, like
this:
row% = 11
leftCol = 36
rightCol = 45
The last step in preparing the menu is to decide on
the colors in which to display the menu. There are
three parts to the menu, each of which must have a
foreground and a background color:
Normal Menu Entries
The Selection Bar Entry
Quick Access Keys
Lets assume we are working on a monochrome display
and assign our colors accordingly (use the COLORCHK
function listed above to determine what kind of
display on which the program is running). Our
normal entries will be white on black, the
selection bar entries will be black on white
(reverse video), and the Quick Access key letters
will be bright white on black. Here's what our
parameter assignments will look like:
fg% = 7 ' White foreground
bg% = 0 ' Black background
hfg% = 0 ' Black foreground
hbg% = 7 ' White background
qfg% = 15 ' Bright White foreground
qbg% = 0 ' Black background
The last step is to make the call to MakeMenu.
Since MakeMenu is a function, you can place it in a
SELECT CASE statement, or any other expression.
Here will simply assign the result (the user's
choice) to the variable s%:
s% = MakeMenu%(choices$(), numOfChoices%,
justify$, leftCol, rightCol,
row%, marker$,
fg%, bg%, hfg%, hbg%,
qfg%, qbg%)
Note that the statement would be contained on a
single line inside your program. This would
return the number of the entry the user selected in
the list. For example, if the user selected "Save
File," the third entry in our list, MakeMenu would
return a value of 3, and place it into the variable
s%. You could then make your program act based on
the user's selection returned by MakeMenu.
page 45
Example: This example will be in two parts. The
first example will reiterate the example used in
the Details above, but in one contiguous piece.
The second example will show the same example using
literal parameters (the "shorthand" method).
' MakeMenu example 1 begins
' Dimension our array to hold menu choices
numOfChoices% = 4
DIM choices$(numOfChoices%)
' Assign menu entries and set Quick Access keys
marker$ = "^"
choices$(1) = "^Load File"
choices$(2) = "^Edit File"
choices$(3) = "^Save File"
choices$(4) = "^Quit"
' Set justification type and screen location
justify$ = "L"
row% = 11
leftCol = 36
rightCol = 45
' Set colors for our menu
fg% = 7 ' White foreground
bg% = 0 ' Black background
hfg% = 0 ' Black foreground
hbg% = 7 ' White background
qfg% = 15 ' Bright White foreground
qbg% = 0 ' Black background
' Make the Menu and get user's response
s% = MakeMenu%(choices$(), numOfChoices%,
justify$, leftCol, rightCol,
row%, marker$,
fg%, bg%, hfg%, hbg%,
qfg%, qbg%)
' You could now act based on user's choice
' MakeMenu example 1 ends
This second version of the above example
illustrates how we don't have to use variables for
everything, but can instead use actual values
(literals). In this case, it's much shorter, but
does exactly the same thing.
' MakeMenu example 2 begins
' Dimension our array to hold menu choices
DIM choices$(4)
' Assign menu entries and set Quick Access keys
choices$(1) = "^Load File"
choices$(2) = "^Edit File"
choices$(3) = "^Save File"
choices$(4) = "^Quit"
page 46
' Make the menu and get user's response
s% = MakeMenu%(choices$(), 4, "C", 36, 45, 11,
"^", 7, 0, 0, 7, 15, 0)
' MakeMenu example 2 ends
Note that the actual MakeMenu call above would be
contained on a single line inside your program.
This method is easier to code, but more difficult
to understand if you come back to it a month later.
Known Limitations: The menu must have at least two
entries but not more than 25. Entry text must be
less than 78 characters. If the selection bar
isn't lining up quite right, change either your
left column or right column parameter by one.
Fiddle with them a bit to make the selection bar
symmetrical.
page 47
Subprogram MAKEWINDOW
-------------------------------------------------------------
Purpose: To make windows on the screen, together
with supporting special effects.
Usage: MakeWindow topRow, leftCol, botRow,
rightCol, foreColor%, backColor%,
windowType%, frameType%,
shadowColor%, explodeType%,
label$
topRow - The top-most row of the window.
leftCol - The left-most column of the
window.
botRow - The bottom-most row of the
window.
rightCol - The right-most column of the
window.
foreColor% - The foreground color of the
window.
backColor% - The background color of the
window.
windowType% - The type of window to make.
See below for details.
frameType% - The type of frame from
which to make the window from.
See below for details.
shadowColor% - The color of the window's
shadow.
explodeType% - Indicates how the window
will be drawn on the screen. See
below for more information.
label$ - A text label for the window, if
desired.
Details: The MakeWindow routine can display a wide
variety of windows in several interesting ways. You
may specify any one of ten different types of
windows made from any of 6 different frame types,
with any color window shadow (or none at all).
Your windows can be drawn normally onto the screen,
or exploded onto the screen for visual impact.
Creating a window involves a little planning. You
must know how big you want your window to be, and
where you want it on the screen. You must decide
the colors for the window, and any visual
embellishments you want, such as shadows or
exploding windows. Let's go through the step by
step process of defining a window.
page 48
We shall assume that we are designing a window that
will hold an error message. The message will never
be more than three lines long. To make it stand
out, we will place the window in the middle of the
screen, with bright yellow text on a red
background. The window will be exploded onto the
screen, and will have a black shadow. We will add
a label to the window indicating that it is an
error message.
To create a window with space for three lines, we
must allow 5 lines of window (3 for the text and
one each for the top and bottom lines of the
frame). Therefore our top row will be 11 and our
bottom row will be 15. This makes 5 lines, so we
set our parameters like this:
topRow = 11
botRow = 15
Our lines will always be less than 65 characters,
so let's allow 70 characters of width. This would
make our left column 6 and our right column 75,
like this:
leftCol = 6
rightCol = 75
To set our foreground and background colors, we
simply make the proper assignments:
foreColor% = 14 ' Bright Yellow
backColor% = 4 ' Red
Now comes the interesting part. We must decide
what type of window we want to use. Below is a
table that illustrates the ten window types
available with the MakeWindow routine:
page 49
WINDOW TYPES
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Type 0 │ │ Type 1 │ │ Type 2 │
│ │ ├─────────────┤ ├─────────────┤
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ ├─────────────┤ │ │
│ │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
┌─────────────┐ ┌──────┬──────┐ ┌─────────────┐
│ Type 3 │ │ Type │ │ │ Type 5 │
│ │ │ 4 │ │ │ │
│ │ │ │ │ │ │
│ │ │ │ │ ├─────────────┤
│ │ │ │ │ │ │
├─────────────┤ │ │ │ │ │
│ │ │ │ │ │ │
└─────────────┘ └──────┴──────┘ └─────────────┘
┌──────┬──────┐ ┌─────────────┐ ┌──────┬──────┐
│ Type │ │ │ Type 7 │ │ │ │
│ 6 │ │ ├──────┬──────┤ │ │ │
│ │ │ │ │ │ │ │ │
├──────┼──────┤ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ ├──────┴──────┤
│ │ │ │ │ │ │ Type 8 │
└──────┴──────┘ └──────┴──────┘ └─────────────┘
┌─────────────┐
│ Type 9 │
├──────┬──────┤
│ │ │
│ │ │
│ │ │
├──────┴──────┤
│ │
└─────────────┘
We will be using window type 0, since we don't need
any internal lines. We set our window type
parameter to 0:
windowType% = 0
The second parameter integral to the appearance of
the window is the frame type. This indicates the
types of lines to use when drawing the windows.
Below is a table illustrating the 6 different frame
types available in the MakeWindow routine:
page 50
FRAME TYPES
┌─────────────┐ ╔═════════════╗ ╓─────────────╖
│ │ ║ ║ ║ ║
├─────────────┤ ╠═════════════╣ ╟─────────────╢
│ │ ║ ║ ║ ║
│ Type 0 │ ║ Type 1 ║ ║ Type 2 ║
│ │ ║ ║ ║ ║
├─────────────┤ ╠═════════════╣ ╟─────────────╢
│ │ ║ ║ ║ ║
└─────────────┘ ╚═════════════╝ ╙─────────────╜
╒═════════════╕ ╔═════════════╗ ┌─────────────┐
│ │ ║ ║ │ │
╞═════════════╡ ╟─────────────╢ ╞═════════════╡
│ │ ║ ║ │ │
│ Type 3 │ ║ Type 4 ║ │ Type 5 │
│ │ ║ ║ │ │
╞═════════════╡ ╟─────────────╢ ╞═════════════╡
│ │ ║ ║ │ │
╘═════════════╛ ╚═════════════╝ └─────────────┘
We will be using frame type 1, a double line frame.
All we have to do is set the parameter variable to
the appropriate value:
frameType% = 1
The next parameter to set is the shadow color. We
will be using a shadow to give our window a 3-D
effect. You can make the shadow any color you like
(0 - 16), but 0 (black) or 16 provides the best
effect. If you do not want a shadow on your window,
send a value of -1 for the shadow color. We want a
black shadow:
shadowColor% = 0
Shadow type 16 is a special type of shadow, and is
a new feature in version 1.5. What it does is
place a window shadow in the normal location, but
the type of shadow is different. It leaves the
characters in the shadow visible, but changes their
colors to plain white. For most application, this
provides a MUCH more realistic shadowing, 3-D
effect. I have adopted it almost universally in my
programs.
To grab the user's attention, and to add a touch of
professionalism, we will explode the window onto
the screen. Exploding the window means make it
appear to grow or expand onto the screen from it's
center point out to its full size. There are four
possible values for the explode type parameter:
page 51
To do this... ...use this Explode Type Value
---------------------------------------------------
■ Place the window on
the screen normally . . . . . . . . . . . . . 0
■ Explode the window
using "Auto" mode . . . . . . . . . . . . . . 1
■ Explode the window
with a horizontal bias . . . . . . . . . . . . 2
■ Explode the window
with a vertical bias . . . . . . . . . . . . . 3
Placing the window on the screen normally means
display it in the ordinary top-to-bottom fashion as
quickly as possible. "Auto" mode means that the
window explosion is automatically adjusted so that
the corners of the window reach the maximum size at
the same time. The horizontal bias mode is used
for very wide and short windows (like our error
message example). Vertical bias mode is used for
tall, narrow windows. You can experiment with the
modes for any particular window and see which mode
suits your needs. If you want to explode your
windows, "Auto" mode is a good place to start.
For our explode type, since our window is wide and
short, we will use mode 2, the Horizontal Bias
mode:
explodeType% = 2
Our last item of interest for our window is the
label. The label is a text header that goes on the
upper-left border of the window, like this:
╔═╡ The LABEL ╞═════════════╗
║ ║
║ ║
║ ║
╚═══════════════════════════╝
Since our example window will be used to display an
error message, our label will say this:
label$ = " Error! "
The final step is to make the call to the
MakeWindow subprogram. The call will look like
this:
MakeWindow topRow, leftCol, botRow,
rightCol, foreColor%, backColor%,
windowType%, frameType%,
shadowColor%, explodeType%,
label$
In your program, this would all be on a single
line. It's broken up here onto several lines for
readability.
page 52
Once your window has been displayed by MakeWindow,
you can do whatever you want with it: fill it with
an error message, for example. MakeWindow can give
your programs a very professional polish.
Example: Two examples will be presented here. The
first will be a reiteration of the example
described in the Details above - a window to
display an error message. It will be in the long
form, with each parameter of the MakeWindow routine
represented by a variable. The second example will
be a shorthand version of the same example, using
actual values (literals) instead of variables.
' MakeWindow example 1 begins
' Assign screen coordinates for window
topRow = 11: botRow = 15
leftCol = 6: rightCol = 75
' Assign colors for the window
foreColor% = 14 ' Bright Yellow
backColor% = 4 ' Red
'Assign window and frame type parameters
windowType% = 0
frameType% = 1
' Assign shadow color and explode type
shadowColor% = 0 ' Black shadow
explodeType% = 2 ' Horizontal bias mode
' Assign our window label
label$ = " Error! "
' Perform the call to MakeWindow
MakeWindow topRow, leftCol, botRow,
rightCol, foreColor%, backColor%,
windowType%, frameType%,
shadowColor%, explodeType%,
label$
' MakeWindow example 1 ends
The second example will be shorter and easier to
code initially, but may be harder to understand if
you come back to your program a month later.
' MakeWindow example 2 begins
MakeWindow 11, 6, 15, 75, 14, 4, 0, 1, 0, 2,
" Error! "
' MakeWindow example 2 ends
This second example is functionally identical to
example 1.
page 53
If you need more examples of MakeWindow, you can
peruse the source code for the DEMO and REF
programs.
Known Limitations: None.
page 54
Subprogram MULTIMENU
-------------------------------------------------------------
Purpose: To create a pull-down menu system for any
application program. Number of menus is limited
only by amount of room on one line.
Usage: MuiltMenu menusArray$(), numEntries%(),
menuTitles%(), justify$, marker$,
shadowCode%, fg%, bg%, hfg%, hbg%,
qfg%, qbg%, menuSelected%,
menuEntrySelected%
menusArray$() - a two-dimensional array
of strings that holds all the menu
choices
numEntries%() - an array of integers that
holds the actual number of choices
for each menu
menuTitles$() - an array of strings that
holds the menu names, or titles,
that are displayed on the top line
justify$ - A single character that tells
the routine how to align the
choices within the menu window
marker$ - A single character that tells
the routine which character to
look for that indicates the "Quick
Access" key for each menu choice.
shadowCode% - a number from -1 to 16 that
tells the routine what kind of
shadow to use for the menu windows
fg%, bg% - the foreground and background
colors of the normal menu entries,
as well as the unhighlighted menu
titles on the top line
hfg%,hbg% - the foreground and background
colors of the highlighted menu
choices, as well as the
highlighted menu titles on the top
line
qfg%,qbg% - the foreground and background
colors of the "Quick Access" keys
for the menu choices, as well as
for the menu titles on the top
line
menuSelected% - this is an OUT parameter,
meaning that when it comes into
the routine, it has no value. When
the routine returns, this variable
contains the number of the menu
the user selected
page 55
menuEntrySelected% - this is an OUT
parameter, meaning that when it
comes into the routine, it has no
value. When the routine returns,
this variable contains the number
of the entry the user selected on
the particular menu they selected
Details: MultiMenu is a very capable pull-down menu
system you can use for any of your programs. It
will do most everything automatically, including
making a window for each menu to the proper size,
placing the menus on the screen in the right place,
and provides a wide variety of movement and
selection keys.
Granted, this routine looks a bit daunting and
complicated. It's not, really. All it requires is
a little planning, and you can have a great
interface for your program. What it creates is a
pull-down menu system very much like the menus in
QuickBASIC. Let's take this one step at a time as
we discuss how to create a menu.
The first step is to plan carefully ahead of time
all the information your menu will require,
including:
- What are the all the functions I want
on my menu system? Write them down.
- How do I want to divide all the
functions in my program into menus,
i.e., categories? Write this down
also.
You should now have a good idea of how your menu
system will be organized. Your categories are the
individual menus, and the functions in those
categories are the individual menu choices. If you
would like an example of this, you can look at the
QuickBASIC menus and how they're organized, or the
menu system on the Screen Builder program. Screen
Builder used MultiMenu for its menus.
The only other planning you'll need to do is decide
what colors you want your menus to use. From now
on, it gets easier. The first step in writing the
code is to set up the three arrays that MultiMenu
needs. The first is the worst, so let's take
some care with it.
The first array is a two-dimensional array, meaning
it has two index values. The first value indicates
the MENU we're talking about, and the second
indicates the CHOICE on the menu referred to by the
first index. Assume we are creating a menu system
page 56
that will have 3 menus in it, with a MAXIMUM of 5
choices per menu. We don't have to use all 5, but
we must allow for the largest case. Our array
dimension would look like this:
DIM menusArray$(1 TO 3, 1 TO 5)
Pretty easy. The first value, 3, is the number of
menus in our system, and the second value, 5, is
the maximum possible number of choices per menu.
The next step is to assign the actual menu choices
to the array. In our example, we will be creating
a menu system for a fictitious Typing Tutor
program. Our 3 menu categories are:
1. File
2. Lessons
3. Practice
Adding our individual functions to the menus would
make our outline look like this:
1. File
1. Start as New Student
2. Load an Old Student
3. Save a Student
4. Quit
2. Lessons
1. Beginner Lesson
2. Intermediate Lesson 1
3. Intermediate Lesson 2
4. Intermediate Lesson 3
5. Advanced Lesson
3. Practice
1. Beginner Practice
2. Intermediate Practice 1
3. Intermediate Practice 2
4. Intermediate Practice 3
5. Advanced Practice
The number on our main outline headings (the menu
titles, 1-3), correspond to the first index of our
array, while the numbers on the subheadings (the
individual menu choices) correspond to the second
array index. We can now assign these values to our
array as follows:
' The first menu's choices
menusArray$(1, 1) = "Start as New Student"
menusArray$(1, 2) = "Load an Old Student"
menusArray$(1, 3) = "Save a Student"
menusArray$(1, 4) = "Quit Typing Tutor"
page 57
' The second menu's choices
menusArray$(2, 1) = "Beginner Lesson"
menusArray$(2, 2) = "Intermediate Lesson 1"
menusArray$(2, 3) = "Intermediate Lesson 2"
menusArray$(2, 4) = "Intermediate Lesson 3"
menusArray$(2, 5) = "Advanced Lesson"
' The third menu's choices
menusArray$(3, 1) = "Beginner Practice"
menusArray$(3, 2) = "Intermediate Practice 1"
menusArray$(3, 3) = "Intermediate Practice 2"
menusArray$(3, 4) = "Intermediate Practice 3"
menusArray$(3, 5) = "Advanced Practice"
The next thing to do is deal with the second array
for this routine. This array tells MultiMenu the
actual number of choices for each menu. This is a
normal one-dimensional array, and the array index
corresponds to the menus. Here we will dimension
the array, and then fill it with values:
' Dimension our array first
DIM numEntries%(1 TO 3)
' Now enter values.
numEntries%(1) = 4 '4 entries in first menu
numEntries%(2) = 5 '5 entries in second menu
numEntries%(3) = 5 '5 entries in third menu
And now our last array, which is an array of
strings that tells MultiMenu the titles of our
menus. It's a normal, one-dimensional array of
strings, and the index refers to the menus. Note
that the values we place in are the headings in our
outline above.
' Dimension an array first
DIM menuTitles$(1 TO 3)
' Now add the menu titles
menuTitles$(1) = "File"
menuTitles$(2) = "Lessons"
menuTitles$(3) = "Practice"
That's the second hardest part. The rest is
simple. First, you must decide how you want the
entries aligned within the window that will be
created for them. You can have the left-justified,
centered, or right-justified. You tell MultiMenu
how to do this by sending it a single character.
Send an "L" for left-justified, a "C" for centered,
or an "R" for right-justified. Let's say we want
our menu choices to be left justified, so we would
use an L, like this:
' Set the justification type
justify$ = "L"
page 58
Now you must decide on a marker character to use.
The marker character is imbedded in the menu titles
and the menu choices and tells MultiMenu which
characters to use as "Quick Access" keys. Simply
place the marker character in the string right
before the character you want MultiMenu to use for
each choice. We now have to modify our menu titles
and menu choices to incorporate the marker
character. We will use the "^" for our marker.
' The first menu's choices
menusArray$(1, 1) = "Start as ^New Student"
menusArray$(1, 2) = "Load an ^Old Student"
menusArray$(1, 3) = "^Save a Student"
menusArray$(1, 4) = "^Quit Typing Tutor"
' The second menu's choices
menusArray$(2, 1) = "^Beginner Lesson"
menusArray$(2, 2) = "Intermediate Lesson ^1"
menusArray$(2, 3) = "Intermediate Lesson ^2"
menusArray$(2, 4) = "Intermediate Lesson ^3"
menusArray$(2, 5) = "^Advanced Lesson"
' The third menu's choices
menusArray$(3, 1) = "^Beginner Practice"
menusArray$(3, 2) = "Intermediate Practice ^1"
menusArray$(3, 3) = "Intermediate Practice ^2"
menusArray$(3, 4) = "Intermediate Practice ^3"
menusArray$(3, 5) = "^Advanced Practice"
' The menu titles
menuTitles$(1) = "^File"
menuTitles$(2) = "^Lessons"
menuTitles$(3) = "^Practice"
Note that when assigning "Quick Access" keys WITHIN
a menu, you must use a unique character for each
menu choice. Also, if you do not wish to implement
the "Quick Access" keys, then simply do not imbed
any marker characters in the choice/title strings.
Now decide on a type of shadow for the menu window.
You have the same shadow types available as those
in the MakeWindow routine, summarized below:
Shadow Value... ...Result
---------------------------------
-1 . . . . . . . . . . No shadow
0-15 . . . . Shadow of this color
16 . . . Special character shadow
Lastly, you must decide on colors to use. Assign
colors to your menu using the following parameters:
fg%, bg% - normal menu choices and titles
hfg%, hbg% - highlighted menu choices and titles
qfg%, qbg% - "Quick Access" keys
page 59
The last two parameters, menuSelected% and
MenuEntrySelected%, do not need values when you
call MultiMenu. MultiMenu will FILL IN values for
these variables when it returns, indicating
The menu the user selected (menuSelected)
The choice on that menu the user selected
(menuEntrySelected)
When MultiMenu returns, you can use the values in
these variables to decide what to do based on the
user's choice. Let's move on to an example now to
see how this all fits together.
Example: We'll use the same example we used above,
except now we'll piece it all together. We're
creating a fictitious Typing Tutor.
' Define a couple quick constants
CONST FALSE = 0, TRUE = NOT FALSE
' MultiMenu example begins
' Dimension arrays for MultiMenu call
DIM menusArray$(1 TO 3, 1 TO 5)
DIM numEntries%(1 TO 3)
DIM menuTitles$(1 TO 3)
' Assign values to our menu choices array
' First menu
menusArray$(1, 1) = "Start as ^New Student"
menusArray$(1, 2) = "Load an ^Old Student"
menusArray$(1, 3) = "^Save a Student"
menusArray$(1, 4) = "^Quit Typing Tutor"
' Second menu
menusArray$(2, 1) = "^Beginner Lesson"
menusArray$(2, 2) = "Intermediate Lesson ^1"
menusArray$(2, 3) = "Intermediate Lesson ^2"
menusArray$(2, 4) = "Intermediate Lesson ^3"
menusArray$(2, 5) = "^Advanced Lesson"
' Third menu
menusArray$(3, 1) = "^Beginner Practice"
menusArray$(3, 2) = "Intermediate Practice ^1"
menusArray$(3, 3) = "Intermediate Practice ^2"
menusArray$(3, 4) = "Intermediate Practice ^3"
menusArray$(3, 5) = "^Advanced Practice"
' Assign the number of entries per menu to
' their array
numEntries%(1) = 4
numEntries%(2) = 5
numEntries%(3) = 5
page 60
' Assign the menu titles to their array
menuTitles$(1) = "^File"
menuTitles$(2) = "^Lessons"
menuTitles$(3) = "^Practice
' Assign a justification type
justify$ = "L"
' Assign a marker character
marker$ = "^"
' Set a shadow type
shadowCode% = 16
' Assign colors. If machine is running color,
' use colors. If mono, use only white, black,
' and bright white. Determine if color using
' QBSCR ColorChk routine.
if ColorChk then ' Machine is color
fg% = 7 ' White
bg% = 1 ' Blue
hfg% = 14 ' Yellow
hbg% = 0 ' Black
qfg% = 15 ' Bright White
qbg% = 1 ' Blue
else ' Machine is monochrome
fg% = 0 ' Black
bg% = 7 ' White
hfg% = 15 ' Bright White
hbg% = 0 ' Black
qfg% = 15 ' Bright White
qbg% = 0 ' Black
end if
' Now make the call to MultiMenu. Do this inside a
' loop, and loop until the user selects quit. Some
' lines may be broken onto two rows, since this is
' only a text file in my word processor. Note that
' the last two parameters have no values going into
' MultiMenu. They will be filled with values
' INSIDE MultiMenu for our use afterwards.
userDone% = FALSE
DO
MultiMenu menusArray$(), numEntries%(),
menuTitles$(), justify$, marker$,
shadowCode%, fg%, bg%, hfg%, hbg%,
qfg%, qbg%, menuSelected%,
menuEntrySelected%
page 61
' At this point, we have returned from
' MultiMenu, and must decide what to do
' based on the user's choice, stored now in
' the variables menuSelected% and
' menuEntrySelected%. For this, we use
' the BASIC CASE statement.
SELECT CASE menuSelected%
CASE 1 ' File Menu
SELECT CASE menuEntrySelected%
CASE 1 ' Start as New Student
' Run routine to start as new student
CASE 2 ' Load an Old Student
' Run routine to load old student
CASE 3 ' Save a Student
' Run routine to save student
CASE 4 ' Quit Typing Tutor
' Run routine to quit. In this case,
' we set our loop flag to TRUE
userDone% = TRUE
CASE 2 ' Lessons Menu
SELECT CASE menuEntrySelected%
CASE 1 ' Beginner Lesson
' Run routine for Beginner Lesson
CASE 2 ' Intermediate Lesson 1
' Run code for Intermediate Lesson 1
CASE 3 ' Intermediate Lesson 2
' Run code for Intermediate Lesson 2
CASE 4 ' Intermediate Lesson 3
' Run code for Intermediate Lesson 3
CASE 5 ' Advanced Lesson
' Run code for Advanced Lesson
CASE 3 ' Practice Menu
SELECT CASE menuEntrySelected%
CASE 1 ' Beginner Practice
' Run code for Beginner Practice
CASE 2 ' Intermediate Practice 1
' Run Intermediate Practice 1
CASE 3 ' Intermediate Practice 2
' Run Intermediate Practice 2
CASE 4 ' Intermediate Practice 3
' Run Intermediate Practice 3
CASE 5 ' Advanced Practice
' Run Advanced Practice code
CASE 0 ' User hit ESC - aborted menu
' Here you could do whatever necessary to
' handle the ESC key. If your menu is up
' all the time, simply ignore it. If your
' menu is supposed to go away when the ESC
' key is hit, then make it go away. In
' this example, the menu goes away, so we
' will exit our loop by setting the loop
' flag to TRUE.
userDone% = TRUE
END SELECT
LOOP UNTIL userDone%
' MultiMenu example ends...finally
page 62
Known Limitations: The number of menus allowed is
limited by the size of a screen row. It will
handle as many as you can fit on one row. Number
of menu entries per menu is limited by the number
of rows on a screen. If you are using a menu
shadow, the number of entries per menu is limited
to 21. Without a shadow, it's 22.
page 63
Subprogram OFFCENTER
-------------------------------------------------------------
Purpose: To center a text string between two points
on the screen that are not themselves centered.
Usage: OffCenter st$, row%, leftCol, rightCol
st$ - The string to center
row% - The row of the screen on which
to center the specified string.
leftCol - The left-most column to center
the text between.
rightCol - The right-most column to center
the text between.
Details: This routine is useful when you want to
center text between two points on the screen that
are themselves not centered on the screen. For
example, you may have a window on the screen
between columns 5 and 30, but want to center some
text inside the window, relative to the window.
This is where OffCenter is useful.
To Center a text string between two points, call
OffCenter and tell it the string you want to
center, the row you want the text on, and the two
points to center the text between.
Example: Let's say we have a window on the screen
that begins on column 5 and ends on column 30. We
then need to center the text "ERROR WARNING" on the
first row of the window, which happens to be row 6.
This is what the OffCenter call would look like:
' OffCenter example begins
OffCenter "ERROR WARNING", 6, 5, 30
' OffCenter example ends
Known Limitations: None.
page 64
Subprogram PUTSCREEN
-------------------------------------------------------------
Purpose: The PutScreen routine will retrieve from
disk a premade screen file (generated with
GetScreen or Screen Builder) and place it on the
display. The whole operation takes less than a
second on a hard disk.
Usage: PutScreen file$
file$ - the disk file that is the screen
to be displayed
Details: This routine is the mechanism whereby
screens that are generated via the GetScreen
routine or the Screen Builder program are placed on
the screen. Simply make a call to PutScreen and it
will load the file from disk and shove it directly
into screen memory. The result is a very fast
display of a premade display.
When you call PutScreen, you send it the name of
the file that stores the screen you want to
display. PutScreen will quickly display it. Study
the example to see just how easy it is.
Example: This example will load a screen that was
previously generated using Screen Builder, and
display it. The screen was saved in a file called
SCREEN01.CLR.
' PutScreen example begins
' Load the screen and display it
PutScreen "SCREEN01.CLR"
' PutScreen example ends
Known Limitations: Works only with QBSCR Screen
Builder or GetScreen generated screens.
page 65
Subprogram QBPRINT
-------------------------------------------------------------
Purpose: Provides an combination of the print,
locate, and color statements in one command. Use
for the print instances where you need to print
characters that PRINT cannot handle, such as ASCII
7, the round bullet.
Usage: QBPrint st$, row%, col%, fore%, back%
st$ - the string or string expression to
be printed
row% - the row of the screen to locate
the string
col% - the column of the screen to locate
the string
fore% - the foreground color in which to
display the string
back% - the background color in which to
display the string
Details: This routine is most useful when you need
to either
- Display a string that has a character(s)
that the QuickBASIC PRINT statement cannot
handle, such as ASCII 7 ( CHR$(7) ). If you
try to say PRINT CHR$(7) to print the round
bullet ASCII character, the speaker will
beep instead, since ASCII 7 is also the bell
character.
- You want to print something in a different
color without having to issue a COLOR
statement. This routine will print a string
in a different color without changing the
current COLOR setting.
- You want to print a string without changing
the current cursor position. This routine
will print at an screen location without
changing the program's current cursor
position.
The QBPrint routine can do this because it writes
your string directly to the display board's memory.
That's why you can print ASCII 7 as a bullet, put
color values into video memory without changing
BASIC's color settings, and locate without moving
the cursor.
page 66
QBPrint supports all screen locations for the
LOCATE portion of its capability, foreground colors
from 0 to 31, and background colors from 0 to 7.
Example: This code segment will display a string
expression on line 10, column 25, with a bright
white foreground and a blue background. It is
broken onto two lines due to the column width.
' QBPrint example begins
' Print a string with characters only QBPrint
' can handle
QBPrint CHR$(7) + " A bulleted string", 10, 25,
15, 1
' QBPrint example ends
Known Limitations: QBPrint is a little slow when it
comes to printing an entire screen of information.
Use it sparingly, and only when necessary. In this
manner, it will be a valuable tool to have around.
page 67
Function SCREENBLANK
-------------------------------------------------------------
Purpose: Provides a screen saver feature to any
program to prevent image "burn-in."
Usage: x$ = ScreenBlank$(delay)
x$ - Any string variable that will
contain the key that was pressed
during the screen blank.
delay - A numerical value that
represents the amount of time to
wait between screen blanker
message shifts.
Details: If your application program leaves the
same image on the screen for any extended period of
time, the image may become "burned in" to the
screen. The result is a ghost image of the display
forever left on the monitor. To prevent this from
happening, you can blank the screen after a defined
period of inactivity. This will prevent the image
from "burning in". However, if the user later
returns and sees a blank screen, what are they to
think? Anything could be wrong with the computer.
What we need is a small message on the screen to
inform the user that the screen has been blanked
out, and they can hit any key to return to the
program. That seems to solve the problem but
there's one twist left: What's to prevent the small
message from itself burning into the screen? The
answer is surprisingly easy. We move the message
around on the screen at periodic intervals. Moving
the message, or "bouncing" it, is easy to do, and
the ScreenBlank routine takes care of all these
features for you.
When you call ScreenBlank, it is assumed that your
program has determined that a period of inactivity
of sufficient duration has elapsed. The delay
parameter is a counter. The larger the value, the
longer the wait between the movements of the
ScreenBlank message. A value of 100,000 is roughly
equal to 3 minutes on a 6 MHz AT-class machine. You
can experiment with the delay to see what suits you
and your machine.
page 68
Example: This example assumes you are checking for
activity in your program. The code that you would
execute if activity occurs is only commentary in
this example. We are representing the main loop
for any program here. The example checks for any
user activity (usually keystrokes). If there is
something to do, it executes any code necessary.
Otherwise, it increments a counter we are using
called wait. The wait counter is used to determine
if the desired period of inactivity has elapsed.
If wait ever reaches our preset limit, we go into
the ScreenBlank. The key pressed by the user to
exit the ScreenBlank is stored in x$, but since we
don't need it here we'll just ignore it.
' ScreenBlank example begins
' Now sitting in some kind of loop
wait = 0: maxWait = 100000
DO
IF AnyUserActivity THEN
' Execute any code necessary
wait = 0
ELSE
wait = wait + 1
IF wait > maxWait then
wait = 0
x$ = ScreenBlank$(50000)
END IF ' wait > maxWait
END IF ' AnyUserActivity
LOOP UNTIL UserQuits
' ScreenBlank example ends
Known Limitations: The delay counter uses a
floating point value (single precision real), so
the delay parameter is limited to the maximum value
for single precision reals.
page 69
Subprogram SCRNRESTORE
-------------------------------------------------------------
Purpose: To restore a portion or all of the screen
saved with the QBSCR SCRNSAVE routine.
Usage: ScrnRestore firstLine%, lastLine%,
scrArray%(), segment
firstLine% - The first line of the
screen to restore.
lastLine% - The last line of the screen
to restore.
scrArray%() - An integer array that
stores the information saved from
the screen via SCRNSAVE. See
below for more information.
segment - The beginning address of
video memory. Use the QBSCR
routine GETVIDEOSEGMENT to obtain
this. See below for details.
Details: Before you use the SCRNRESTORE routine,
you have to have something to restore to the
screen. In the normal course of events you would
save a portion or all of the screen using the
SCRNSAVE routine, display something over the
existing screen like a window, and then restore the
screen when finished with the window using
SCRNRESTORE.
To use the SCRNRESTORE routine, we can assume you
have saved a part or all of the display using
SCRNSAVE. There are points that need to be
understood before either the SAVE or RESTORE can be
used. The first is that when you save part of the
screen, the information saved is stored in an
array. The array must be an integer array, and it
must have 4000 elements. To dimension such an
array, use the following sort of DIM statement:
DIM scrArray%(4000)
This provides you an array in which to store the
screen information. This array is passed to the
SCRNRESTORE (or SAVE) routine, so that that it has
something to read from (or store to).
The second concept of importance is that the
SCRNRESTORE (and SAVE) routine know the location of
the beginning of the video card memory. This is
simply a value, and it can easily be obtained using
page 70
the GETVIDEOSEGMENT function in the QBSCR package.
All you have to do is obtain a segment value using
this function, like this:
segment = GetVideoSegment
And then pass the segment parameter to the
SCRNRESTORE (or SAVE) routine, like this:
ScrnRestore 1, 25, scrArray%(), segment
The first and last lines specify the range of lines
on the screen to actually save. The example above
would save the entire screen (lines 1 through 25).
See the example below for usage.
Example: This example uses the SCRNSAVE routine to
save a part of the screen. An error message is
then displayed over the screen. Finally, the
screen is restored with SCRNRESTORE when the user
hits a key.
' ScrnRestore example begins
' Dimension an array to store the screen contents
DIM scrArray%(4000)
' Assign first and last line parameters for both
' SAVE and RESTORE (they are the same). Saving
' only the lines that will be overwritten by the
' error message.
first% = 11
last% = 15
' Obtain the proper video memory segment
segment = GetVideoSegment
' Save the designated portion of the screen
ScrnSave first%, last%, scrArray%(), segment
' Display the error message - this code commented
' out. You would display something on the screen
' on lines 11 through 15.
' Wait for a keypress.
keyPress$ = INPUT$(1)
' Restore the screen after the user hits a key.
ScrnRestore first%, last%, scrArray%(), segment
' ScrnRestore example ends
For more information in the form of examples, see
the source code for the DEMO program or the
Techniques section of this manual.
Known Limitations: None.
page 71
Subprogram SCRNSAVE
-------------------------------------------------------------
Purpose: To save a portion or all of the screen
before overwriting it with something else.
Usage: ScrnSave firstLine%, lastLine%,
scrArray%(), segment
firstLine% - The first line of the
screen to save.
lastLine% - The last line of the screen
to save.
scrArray%() - An integer array that
stores the information saved from
the screen.
segment - The beginning address of
video memory. Use the QBSCR
routine GETVIDEOSEGMENT to obtain
this. See below for details.
Details: In the normal course of events you would
save a portion or all of the screen using the
SCRNSAVE routine, display something over the
existing screen like a window, and then restore the
screen when finished with the window using
SCRNRESTORE.
There are points that need to be understood before
either the SAVE or RESTORE can be used. The first
is that when you save part of the screen, the
information saved is stored in an array. The array
must be an integer array, and it must have 4000
elements. To dimension such an array, use the
following sort of DIM statement:
DIM scrArray%(4000)
This provides you an array to store the screen
information. This array is passed to the
SCRNSAVE (or RESTORE) routine, so that that it has
something in which to save the screen information.
The second concept of importance is that the
SCRNSAVE (and RESTORE) routine know the location of
the beginning of the video card memory. This is
simply a value, and it can easily be obtained using
the GETVIDEOSEGMENT function in the QBSCR package.
All you have to do is obtain a segment value using
this function, like this:
page 72
segment = GetVideoSegment
And then pass the segment parameter to the
SCRNSAVE (or RESTORE) routine, like this:
ScrnSave 1, 25, scrArray%(), segment
The first and last lines specify the range of lines
on the screen to actually save. The example above
would save the entire screen (lines 1 through 25).
See the example below for usage.
Example: This example uses the SCRNSAVE routine to
save a part of the screen. An error message is
then displayed over the screen. Finally, the
screen is restored with SCRNRESTORE when the user
hits a key.
' ScrnSave example begins
' Dimension an array to store the screen contents
DIM scrArray%(4000)
' Assign first and last line parameters for both
' SAVE and RESTORE (they are the same). Saving
' only the lines that will be overwritten by the
' error message.
first% = 11
last% = 15
' Obtain the proper video memory segment
segment = GetVideoSegment
' Save the designated portion of the screen
ScrnSave first%, last%, scrArray%(), segment
' Display the error message - this code commented
' out. You would display something on the screen
' on lines 11 through 15.
' Wait for a keypress.
keyPress$ = INPUT$(1)
' Restore the screen after the user hits a key.
ScrnRestore first%, last%, scrArray%(), segment
' ScrnSave example ends
For more information in the form of examples, see
the source code for the DEMO program or the
Techniques section of this manual.
Known Limitations: None.
page 73
Subprogram WIPE
-------------------------------------------------------------
Purpose: To clear a programmer-defined portion of
the screen.
Usage: Wipe top%, bottom%, lft%, rght%, back%
top% - The top-most row to clear
bottom% - The bottom-most row to clear
lft% - The left-most column to clear
rght% - The right-most column to clear
back - The background color with
which to clear the screen.
Details: The Wipe routine is used to clear selected
portions of the screen. It is particularly useful
for clearing the contents from existing windows so
that they can be reused.
All you need do to use Wipe is to specify the left,
right, top, and bottom coordinates of the
rectangular area to clear. Wipe will always clear
the INSIDE of the area you specify. In other
words, if you tell it to clear an area where
top% = 5
bottom% = 10
lft% = 10
rght% = 70
Wipe would actually clear an area of
top% = 6
bottom% = 9
lft% = 11
rght% = 69
It does this so that if you have a window to clear
out, you can call Wipe with the same coordinates as
your window without erasing your screen border.
Makes using Wipe much easier.
The back% parameter indicates the color to use when
clearing out the defined area, and should be the
same color as the existing background.
Example: The following example will assume we have
a window at the above listed coordinates, and we
wish to clear it out for reuse. The background
color of this window is blue.
page 74
' Wipe example begins
' Set our parameter variables for area to clear
top% = 5
bottom% = 10
lft% = 10
right% = 70
' Set our background color with which to clear
back% = 1 ' Blue
' Wipe the area clear
Wipe top%, bottom%, lft%, rght%, back%
' Wipe example ends
Known Limitations: None.
page 75
Techniques for Using QBSCR
-------------------------------------------------------------
Since providing documentation for the routines
won't tell you how to perform specific tasks, this
manual has this section which details some of the
techniques possible with the QBSCR routines.
The techniques described in here will not only
clarify the usage of some of the routines, but will
also show you how to combine the routines to
accomplish specific tasks. These techniques will
add professionalism to any program that yearns for
it.
Simply choose the section you have interest in, and
the documentation will attempt to detail the
technique in terms of why it is used, what it can
do for you, and how to do it.
page 76
Displaying and Popping a Window from the Screen
-------------------------------------------------------------
Many programs add professionalism to their
appearance using this technique. The effect can be
described as laying a window on top of an existing
display and when its usefulness has elapsed, it is
"popped," or quickly removed from the screen, and
the underlying display remains intact. While this
is what appears to happen, the mechanics are a bit
different.
This is what actually happens:
1) The initial display exists on the screen.
2) The contents of the video card memory,
which contains the text on the screen and
the color attribute of each character, is
saved inside the program (in our case, in
an integer array).
3) The new window is is written to the display
overwriting and destroying the portion of
the display it now occupies.
4) When the window is to be removed or popped
from the screen, what actually happens is
that the contents of the video memory saved
in step 2 before the new window was
displayed is now restored to video memory.
This causes the old saved information to be
redisplayed.
The window has been effectively displayed and then
popped from the display when it was no longer
needed. We can easily perform this task with the
QBSCR Screen Routines. Specifically, we will need
the services of the SCRNSAVE, MAKEWINDOW, and
SCRNRESTORE routines. The same step-by-step
process above applies here:
1) Display the initial screen. This can be
displayed during the normal course of
program execution. Any existing display
can be saved/restored.
2) Save the screen contents into an integer
array using the SCRNSAVE routine.
3) Place the new window on the screen using
the MAKEWINDOW routine. You can then print
any text inside the window you need.
page 77
4) As soon as you are finished with the
window, you can restore the original screen
contents, thus popping the window off the
display, using the SCRNRESTORE routine.
The use of windows is extremely useful for
isolating a single thought, concept or activity on
your display screen. Using this technique will
allow you to use windows while retaining the
integrity of the underlying screen. This will
result in much faster execution time and happier
users, since you and they don't have to wait to
redraw the whole screen.
We'll now go through a practical example of the
entire process. To use an earlier example, our
task is to display an error message in the middle
whatever screen currently exists on the display.
Who knows when an error will come up? We will
assume that there is some sort of event that
triggers the error - we're only going to worry
about displaying the error in a window and then
restoring the display. Other assumptions are:
1) The error message will never be more than 5
lines long, each of which will be 60
characters or less in length. This means
we will need 7 display lines (5 lines of
error text + 2 lines for the window frame).
2) The user will hit a key to clear the error
message window from the screen, signifying
that they are finished reading it.
3) The software will be running on a color
display.
4) There will be a routine called ErrorMessage
that will place the appropriate text for
the error message inside our window.
So let's begin our example. The code here will be
commented well so that it is clear what's
happening.
' Window display/removal example begins
' Dimension an array to store screen contents
DIM scrArray%(4000)
' Save the portion of the screen we will be
' overwriting. Our window will always be
' located between rows 10 and 16. First
' though, we need the proper video segment.
segment = GetVideoSegment
' Now we can save the portion of the screen we will
' be overwriting.
ScrnSave 10, 16, scrArray%(), segment
page 78
' We've now paid our insurance - lets display the
' error message window. We will assign our window
' parameters as variables for readability.
leftCol = 8: rightCol = 73
topRow = 10: botRow = 16
foreColor% = 15 ' Bright White
backColor% = 4 ' Red
windowType% = 0 ' Normal window, no inside lines
frameType% = 1 ' All double lines
shadowColor% = 0 ' Black window shadow
explodeType% = 1 ' Automatic explode mode
label$ = " Error! "
' Make the window on the screen. Note that in your
' real program this next statement would be on a
' single line.
MakeWindow topRow, leftCol, BotRow, rightCol,
foreColor%, backColor%, windowType%,
frameType%, shadowColor%, explodeType%,
label$
' Add the error text to the window. We will assume
' that there is a routine called ErrorMessage that
' will place the correct message at the right spot
' on the screen.
ErrorMessage
' Wait for the user to hit a key, signifying that
' they are finished with the message.
keyPress$ = INPUT$(1)
' Now that the user is done, we will restore the
' screen to the state it was in before the error
' message window was displayed using SCRNRESTORE.
ScrnRestore 10, 16, scrArray%(), segment
' Window display/removal example ends
Note that you should only save and restore the
smallest amount of the screen as you need to. Doing
so will result in much faster performance.
This technique can be used for multiple windows
simultaneously by having an integer array for each
window you place on the screen. Save the screen
with a new array each time you add a new window to
the screen. In this way, you can reverse the order
when you restore screens, and the windows will be
removed from the display one at a time in order.
page 79
Visual Effects with BUILDSCREEN and CLRSCR
-------------------------------------------------------------
BuildScreen and ClrScr are complimentary routines.
Although one creates screens and the other destroys
them, they perform these tasks in the same way. If
you look at the source code for each routine,
you'll see that they are very similar. Each
routine also supports exactly the same modes of
animation. ClrScr mode 10, for example, will clear
the screen in a spiral fashion, while BuildScreen
mode 10 displays a screen in the same spiral
fashion.
Since the modes of animation are the same for each
routine, they can be used together to create
interesting visual effects. A perfect example is
demonstrated in the DEMO program. This example
uses complimentary ClrScr and BuildScreen routines.
ClrScr is used to first clear the screen using
ASCII character 176 (░) with mode 3, which
resembles curtains closing on a stage. Then the
display is placed on the screen using BuildScreen
mode 2, which is the complimentary opposite mode of
mode 3 just used with ClrScr. The effect looks
likes curtains closing on the existing display, and
the curtains open again revealing the new display.
Techniques like this can be generated easily for
opening screens of programs or other displays. For
details on the example described above, see the
source code for the DEMO program. Other modes that
match well can be used to create similar effects.
Use the REF program to see all the ClrScr and
BuildScreen modes. By playing around a bit, you
may discover an impressive way to open your own
program.
page 80
Window Making Techniques
-------------------------------------------------------------
Creating a "Frameless" Window
---------------------------------------------------
Sometimes you don't want a border, or frame, around
your window. You just want a colored field. You
can do this two ways.
The first and most obvious method is to use the
MakeWindow routine. You can do this easily by
making the foreground and background color
parameters the same value. If for instance you
wanted to make a red frameless window, simply make
the foreColor and backColor parameters the same, in
our case, 4. It doesn't matter what the frameType
or windowType parameters are since you won't see
them. Choose any valid value such as zero for both
parameters.
The drawback with this technique is that you must
provide all the MakeWindow parameters. There is a
shortcut for creating a frameless window. You do
so by using the Wipe routine. Simply pass Wipe the
coordinates for your window and a color for the
field. This results in the much easier creation of
a frameless window.
Of course, if you want a shadow for the window, or
you want it to explode onto the screen, the first
option is your best bet. Frameless windows, by the
way, look great with a black shadow.
Window Shadows
---------------------------------------------------
And speaking of window shadows, the new shadow mode
that MakeWindow incorporates will add a definite
touch of professionalism to any program that uses
windows.
The new shadow type is 16, and will leave existing
characters in the shadowed region on the screen.
It will, however, change the color of the
characters so they are in plain white (color 7).
This is exactly the same shadowing that the
QuickBASIC environment uses, and looks very sharp.
If you plan to be using color displays, then
seriously consider this shadow mode.
page 81
Menu Techniques
-------------------------------------------------------------
Producing a Clear and Clean Menu
---------------------------------------------------
When generating menus for a person to use, it's
important to keep a couple of design concepts in
mind.
Your menus should be easy to use and understand.
This means keeping the menu focused without too
many choices. Users tend to work best when they
have nine or fewer choices to decide between. The
choices themselves should be concise yet distinct.
There shouldn't be any question about what a
particular entry does. You can accomplish these
goals by giving your entries careful thought. Make
sure each is meaningful, and keep your menu choices
to as few as possible.
There are specific things you can do with the QBSCR
MakeMenu function to further these aims.
1) Keep your menu entries to a minimum and
make sure they are clear.
2) Use "Quick Access" keys to make your menus
easier to use. By providing both a
selection bar and Quick Access keys, you
satisfy the needs of both the novice and
the advanced user.
3) Choose your Quick Access Keys carefully.
Specifically, choose ones that are easy to
remember. For instance, if your entry is
"Save File," the S would make an excellent
Quick Access key, since S is closely
related to the primary function of the
entry, Saving a file. The V wouldn't be
terrible, but the F would be the worst,
since you might also have "Edit File" and
"Load File" entries. The F would not
distinguish the Save function from any of
the other file operations.
4) Always provide on-screen instructions on
how to use the menu.
page 82
5) Keep your menus clean. Isolate them from
any other distracting screen information.
You can do this by
a) choosing a location on the screen
that is as removed as possible from
other information on the screen,
and
b) placing your menu inside a window.
If you place your menu inside a window, it
isolates the menu even further from the
rest of the world. This will help the user
focus on the menu and the decision to be
made there.
While all these ideas may sound odd or picky, they
all come together to make your menus more
presentable, easy to use, and professional. The
user may not be thinking "Wow, this menu is nicely
isolated and that makes it easier for me to deal
with," but it inherently will be. Their overall
impression will be more favorable, even if they
don't specifically know why. They should at least
get the impression that the program is well
organized.
page 83
Cross Reference - Routine Dependencies
-------------------------------------------------------------
To make code more efficient, some of the QBSCR
routines make use of each other's services. This
section of the documentation will detail exactly
what routines are dependent on others, and on which
ones. Consult this table carefully if you plan to
be pruning off routines your particular program
will not be using.
Also note that there are two routines in the QBSCR
package that are not documented except here. They
are the function SubMenu and the subprogram
DisplayEntry. They are used only internally by
other routines, which are detailed below.
Routine... ...is dependent on
---------------------------------------------------
Banner . . . . . . . . . . . . . . . . . . . . none
BlockRestore . . . . . . . . . . . . . . . . . none
BlockSave . . . . . . . . . . . . . . . . . . none
BlockSize . . . . . . . . . . . . . . . . . . none
BuildScreen . . . . . . . . . . . GetVideoSegment
Center . . . . . . . . . . . . . . . . . . . . none
ClrScr . . . . . . . . . . . . . . . . . . . . none
ColorChk . . . . . . . . . . . . . . . . . . . none
DisplayEntry . . . . . . . . . . . . . . . . . none
GetBackground . . . . . . . . . . GetVideoSegment
GetForeground . . . . . . . . . . GetVideoSegment
GetScreen . . . . . . . . . . . . GetVideoSegment
GetString . . . . . . . . . . . . . . . . . . none
GetVideoSegment . . . . . . . . . . . . . . . none
MakeMenu . . . . . . . . . . . . . . . DisplayEntry
MakeWindow . . . . . . . . . . . . GetVideoSegment
MultiMenu . . . . . . . . . . . . . . BlockRestore
BlockSave
DisplayEntry
GetVideoSegment
MakeWindow
SubMenu
OffCenter . . . . . . . . . . . . . . . . . . none
PutScreen . . . . . . . . . . . . GetVideoSegment
QBPrint . . . . . . . . . . . . . GetVideoSegment
ScreenBlank . . . . . . . . . . . . . . . . . none
ScrnRestore . . . . . . . . . . . . . . . . . none
ScrnSave . . . . . . . . . . . . . . . . . . . none
SubMenu . . . . . . . . . . . . . . . DisplayEntry
Wipe . . . . . . . . . . . . . . . . . . . . . none
page 84
Closing Notes
-------------------------------------------------------------
I sincerely hope that the QBSCR Screen Routines are
of some help to you, either in a productivity or a
tutorial capacity. The Screen Routines try their
best to fill both roles.
The BAD SOFTWARE Company has two missions in the
world of software for the IBM PC and compatibles.
The first is to provide useful software that's easy
to use. The primary purpose of any software is
that it does something you want or need. Therefore,
BAD SOFTWARE is dedicated to the development of
software that has these qualities. But the second
item of importance to BAD SOFTWARE is that software
be fun. Computing need not be a chore to avoid.
The QBSCR Screen Routines hopefully fulfill this
requirement. It's always been fun for me to make
my own programs appear as professional as possible,
and the Screen Routines let me do this while
expending very little time and effort. I can only
hope that they will do the same for you.
If you have any comments or ideas about the Screen
Routines, please feel free to drop me a letter at
the following address. I'll do my best to answer
all correspondence.
Tony Martin
1611 Harvest Green Ct.
Reston, VA 22094
Lastly, I must acknowledge a few copyrights.
Microsoft and QuickBASIC are trademarks of
Microsoft Corporation. I'm sure you didn't know
this...
page 85
Registration Form
-------------------------------------------------------------
If you decide to register the QBSCR Screen
Routines, send a check for $15.00 U.S. made out to
Tony Martin to:
Tony Martin
1611 Harvest Green Ct.
Reston, VA 22094
In return I will send you an official disk set
containing all the files of the latest version of
the Screen Routines. In addition you will receive
a free copy of the LASER graphics entertainment
program written by BAD SOFTWARE exclusively for
registered users of BAD SOFTWARE products.
---------------------------------------------------
Complete this registration form and send with your
check to the above listed address.
Product: QBSCR Screen Routines
Version: 1.5
Cost $15.00
Quantity: ________
Total: $__________
Ship to:
Name:______________________________________________
Address: __________________________________________
City/State/Zip: ___________________________________
page 86